**میعین** *(Miein)* که به تازگی از [**کوئرا** *(Quera)*](https://quera.org/) به [**جونیورا** *(Juniora)*](https://juniora.org/) فرار کرده است، پس از مدتی متوجه شده است که حتی **جونیورا** نیز **نمیتواند میزبان رویاهای بلندپروازانهی او باشد!** او که پس از دیدن بنر **مسابقه استخدامی** [**ایرانسرور** *(IranServer)*](https://www.iranserver.com/) در کوئرا و مراجعه به وبسایت آن، با شعار _**"سریع، امن و همیشه همراه در مسیر رشد کسب و کار"**_ مواجه شده است حالا مطمئن شده که ایرانسرور همان **سرزمین رویاهای او** خواهد بود.
از آنجایی که رسیدن به **هیچ سرزمین رویاهایی** بدون چالش و دشواری **امکان پذیر نیست،** میعین باید **چالش ایرانسروری** زیر را حل کند تا بتواند مراحل استخدام در این مجموعه را با موفقیت طی کند!

# جزئیات پروژه
پروژهی اولیه را از [این لینک](/contest/assignments/81560/download_problem_initial_project/279969/) دانلود کنید.
<details class="yellow">
<summary>
**ساختار فایلها**
</summary>
```
miein-farari
├── app
│ ├── Http
│ │ ├── Controllers
│ │ │ └── <mark class="orange" title="این فایل باید بهینه سازی شود">UserController.php</mark>
│ ├── Models
│ │ ├── <mark class="orange" title="این فایل باید پیاده سازی شود">User.php</mark>
│ │ ├── <mark class="orange" title="این فایل باید پیاده سازی شود">Service.php</mark>
│ │ ├── <mark class="orange" title="این فایل باید پیاده سازی شود">Invoice.php</mark>
│ │ └── <mark class="orange" title="این فایل باید پیاده سازی شود">Ticket.php</mark>
├── database
│ ├── factories
│ │ ├── <mark class="orange" title="این فایل باید پیاده سازی شود">UserFactory.php</mark>
│ │ ├── <mark class="orange" title="این فایل باید پیاده سازی شود">ServiceFactory.php</mark>
│ │ ├── <mark class="orange" title="این فایل باید پیاده سازی شود">InvoiceFactory.php</mark>
│ │ └── <mark class="orange" title="این فایل باید پیاده سازی شود">TicketFactory.php</mark>
│ ├── migrations
│ │ ├── <mark class="orange" title="این فایل باید پیاده سازی شود">2024_02_26_000000_create_users_table.php</mark>
│ │ ├── <mark class="orange" title="این فایل باید پیاده سازی شود">2024_02_26_000001_create_services_table.php</mark>
│ │ ├── <mark class="orange" title="این فایل باید پیاده سازی شود">2024_02_26_000002_create_invoices_table.php</mark>
│ │ └── <mark class="orange" title="این فایل باید پیاده سازی شود">2024_02_26_000003_create_tickets_table.php</mark>
│ ├── seeders
│ │ └── <mark class="orange" title="این فایل باید پیاده سازی شود">DatabaseSeeder.php</mark>
├── routes
│ └── web.php
├── tests
├── README.md
├── artisan
├── composer.json
├── composer.lock
├── package.json
├── phpunit.xml
├── server.php
└── webpack.mix.js
```
</details>
<details class="grey">
<summary>
**راهاندازی پروژه**
</summary>
**برای اجرای پروژه، باید `php` و `composer` را از قبل نصب کرده باشید.**
+ ابتدا پروژهی اولیه را دانلود و از حالت فشرده خارج کنید.
+ دستور `composer install` را در پوشهی اصلی پروژه برای نصب نیازمندیها اجرا کنید.
+ برای اجرای مایگریشنها از دستور `php artisan migrate` استفاده کنید.
</details>
**میعین** در چالش ایرانسروری باید بخشی از **مدلها**، **مایگریشنها**، **سیدر** و **فکتوریهای** ایرانسرور را در یک **پروژه لاراولی** پیادهسازی کند. همچنین او در نهایت قرار است تا **یک مشکل رایج** در کار با دیتابیسها را در بخشی از یکی از کنترلرهایی که از قبل در وبسایت ایرانسرور وجود دارد را **برطرف** کند! توضیح مواردی که باید پیادهسازی شوند به شکل زیر میباشد:
## **پیادهسازی جداول و نوشتن مایگریشنها** *(Migrations)*
در این بخش میعین باید مایگریشنهای مربوط به ایجاد جداول `users`، `services`، `invoices` و `tickets` را که به ترتیب مربوط به **اطلاعات کاربران**، **سرویسهای ارائهشده توسط ایرانسرور به هر کاربر**، **صورتحسابهای سرویسها** و **تیکتهای پشتیبانی ارسالی کاربران** میباشند را پیادهسازی کند. ساختار مربوط به هر کدام از جداول در بخش زیر مشخص است:
<details class="blue">
<summary>
**ساختار جدول** `users` و **پیادهسازی مایگریشن** `create_users_table`
</summary>
## **ساختار جدول** `users`
| نام ستون | نوع داده | توضیحات |
| ------------------- | ----------- | ---------------------- |
| `id` | `bigint` | کلید اصلی |
| `name` | `string` | نام کاربر |
| `email` | `string` | ایمیل (منحصربهفرد) |
| `email_verified_at` | `timestamp` | زمان تأیید ایمیل |
| `password` | `string` | رمز عبور |
| `remember_token` | `string` | توکن احراز هویت |
| `created_at` | `timestamp` | زمان ایجاد |
| `updated_at` | `timestamp` | زمان آخرین بهروزرسانی |
</details>
<details class="blue">
<summary>
**ساختار جدول** `services` و **پیادهسازی مایگریشن** `create_services_table`
</summary>
## جدول `services`
| نام ستون | نوع داده | توضیحات |
| ------------ | -------------- | -------------------------- |
| `id` | `bigint` | کلید اصلی |
| `user_id` | `bigint` | کلید خارجی به جدول `users` |
| `name` | `string` | نام سرویس |
| `price` | `decimal(8,2)` | قیمت سرویس |
| `created_at` | `timestamp` | زمان ایجاد |
| `updated_at` | `timestamp` | زمان آخرین بهروزرسانی |
</details>
<details class="blue">
<summary>
**ساختار جدول** `invoices` و **پیادهسازی مایگریشن** `create_invoices_table`
</summary>
## جدول `invoices`
| نام ستون | نوع داده | توضیحات |
| ------------ | -------------- | ----------------------------- |
| `id` | `bigint` | کلید اصلی |
| `service_id` | `bigint` | کلید خارجی به جدول `services` |
| `amount` | `decimal(8,2)` | مبلغ صورتحساب |
| `paid_at` | `timestamp` | زمان پرداخت |
| `created_at` | `timestamp` | زمان ایجاد |
| `updated_at` | `timestamp` | زمان آخرین بهروزرسانی |
</details>
<details class="blue">
<summary>
**ساختار جدول** `tickets` و **پیادهسازی مایگریشن** `create_tickets_table`
</summary>
## جدول `tickets`
| نام ستون | نوع داده | توضیحات |
| ------------- | ----------- | -------------------------- |
| `id` | `bigint` | کلید اصلی |
| `user_id` | `bigint` | کلید خارجی به جدول `users` |
| `subject` | `string` | موضوع تیکت |
| `description` | `text` | توضیحات تیکت |
| `status` | `string` | وضعیت (`open` یا `closed`) |
| `created_at` | `timestamp` | زمان ایجاد |
| `updated_at` | `timestamp` | زمان آخرین بهروزرسانی |
</details>
## **پیادهسازی مدلها**
لیست بخشی از مدلهای ایرانسرور به شرح زیر است که باید **به همراه روابطشان** در پروژه پیادهسازی شوند:
+ **مدل** `User`**:** کاربران *ایرانسرور*
+ **مدل** `Service`**:** سرویسهایی که *ایرانسرور* به هر کاربر ارائه میدهد
+ **مدل** `Invoice`**:** صورتحسابهای پرداختی مربوط به سرویسهای ارائه شده
+ **مدل** `Ticket`**:** تیکتهای پشتیبانی ارسال شده توسط کاربران
## **پیادهسازی روابط بین مدلها**
+ هر **کاربر** میتواند چندین **سرویس** داشته باشد.
+ هر **سرویس** به یک **کاربر** تعلق دارد.
+ هر **سرویس** میتواند چندین **صورتحساب** داشته باشد.
+ هر **صورتحساب** به یک **سرویس** تعلق دارد.
+ هر **کاربر** میتواند چندین **تیکت پشتیبانی** ایجاد کند.
+ هر **تیکت پشتیبانی** متعلق به یک **کاربر** است.
## **پیادهسازی فکتوریها** *(Factories)*
میعین باید فکتوریهای زیر را در این چالش پیادهسازی کند تا در مرحله بعد با استفاده از یک **دیتابیس سیدر** *(Seeder)* **دادههای تصادفی** برای تست برنامه نوشته شده ایجاد کند. برای بررسی بیشتر هر کدام از فکتوریها روی بخشهای زیر کلیک کنید:
<details class="red">
<summary>
**ساختار فکتوری** `InvoiceFactory`
</summary>
### **فکتوری** `InvoiceFactory`
| نام ستون | توضیحات | مقادیر ممکن |
| ---------- | ----------------------------- | --------------------------- |
| `service_id` | کلید خارجی به جدول `services` | مقدار یک `service_id` معتبر |
| `amount` | مبلغ صورت حساب | عدد اعشاری بین ۱۰ تا ۱۰۰ |
| `paid_at` | زمان پرداخت | `null` یا یک تاریخ تصادفی |
</details>
<details class="red">
<summary>
**ساختار فکتوری** `ServiceFactory`
</summary>
### **فکتوری**`ServiceFactory`
| نام ستون | توضیحات | مقادیر ممکن |
| -------- | -------------------------- | ------------------------ |
| `user_id` | کلید خارجی به جدول `users` | مقدار یک `user_id` معتبر |
| `name` | نام سرویس | یک کلمه تصادفی |
| `price` | قیمت سرویس | عدد اعشاری بین ۱۰ تا ۱۰۰ |
</details>
<details class="red">
<summary>
**ساختار فکتوری** `TicketFactory`
</summary>
### **فکتوری** `TicketFactory`
| نام ستون | توضیحات | مقادیر ممکن |
| ----------- | -------------------------- | ------------------------ |
| `user_id` | کلید خارجی به جدول `users` | مقدار یک `user_id` معتبر |
| `subject` | موضوع تیکت | یک جمله تصادفی |
| `description` | توضیحات تیکت | یک پاراگراف تصادفی |
| `status` | وضعیت تیکت | `open` یا `closed` |
</details>
<details class="red">
<summary>
**ساختار فکتوری** `UserFactory`
</summary>
### **فکتوری** `UserFactory`
| نام ستون | توضیحات | مقادیر ممکن |
| ----------------- | ------------------- | ----------------------- |
| `name` | نام کاربر | نام تصادفی |
| `email` | ایمیل کاربر (یونیک) | ایمیل تصادفی معتبر |
| `email_verified_at` | زمان تأیید ایمیل | زمان فعلی |
| `password` | رمز عبور | کلمه `password` به صورت هش شده |
| `remember_token` | توکن یادآوری | رشته ۱۰ کاراکتری تصادفی |
</details>
## **پیادهسازی سیدر** *(Seeder)*
یک **سیدر** *(Seeder)* با عنوان `DatabaseSeeder` در پروژه اولیه وجود دارد که باید به شکل زیر برای ایجاد دادهها در دیتابیس **با استفاده از فکتوریهای پیادهسازی شده** مورد استفاده قرار بگیرد:
1. دقیقا **۱۰ کاربر** با استفاده از **فکتوری** `User` ایجاد میشوند.
2. **هر کاربر دقیقا ۵ سرویس** با استفاده از **فکتوری** `Service` خواهد داشت، پس در نهایت باید **۵۰ سرویس** ثبت شود.
3. **هر کاربر به صورت تصادفی بین ۳ تا ۵ صورتحساب** با استفاده از **فکتوری** `Invoice` برای سرویسهای مختلف خود دارد. توجه داشته باشید که **تعداد کل صورتحسابهای کاربر بین ۳ تا ۵ صورتحساب میباشد** و این مقدار **به ازای هر کدام از سرویسهای کاربر نیست.**
4. **هر کاربر به صورت تصادفی بین ۰ تا ۱۰ تیکت** با استفاده از **فکتوری** `Ticket` دارد.
## **بهینهسازی یک مشکل اساسی در کنترلر** `UserController`
کنترلر `UserController` به شکل زیر از قبل در **فایلهای پروژه اولیه** پیادهسازی شده است که با دریافت تمامی کاربران موجود در برنامه در ویو `users.index` لیست کاربران به همراه هر کدام از سرویسهای مربوط به آنها و هر کدام از صورتحسابهای مربوط به هر کدام از آن سرویسها را نمایش میدهد. پیادهسازی انجام شده به شکل **بهینهای نیست** و **دارای مشکل است** که میعین باید این مشکل را نیز در پروژه ارسالی خود **برطرف** سازد:
```php App\Http\Controllers laravel
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\User;
class UserController extends Controller
{
public function index()
{
$users = User::all();
return view('users.index', compact('users'));
}
}
```
# آنچه باید آپلود کنید
+ **توجه**: پس از پیادهسازی موارد خواسته شده، کل فایلهای پروژه بهجز پوشهی `vendor` را زیپ کرده و ارسال کنید.
+ **توجه**: شما مجاز به افزودن فایل جدیدی در این ساختار **نیستید** و تنها باید تغییرات را در فایلهای موجود اعمال کنید.
+ **توجه**: که نام فایل _Zip_ اهمیتی **ندارد**.
ارسال پاسخ برای این سؤال
در حال حاضر شما دسترسی ندارید.