وضعیتهای عملیاتی workflow — تعریف و اتصال به وضعیت
> version: 1.15 | last_updated: 2026-09-20 | audience: admin
ایده
عملیات را **جدا** تعریف میکنید؛ بعد به **وضعیت داخل دپارتمان** وصل میکنید.
```
کاتالوگ عملیات → وضعیت دپارتمان → کیس کارتابل
(تعریف) (اتصال) (اجرا)
```
انواع عملیات
| نوع | محتوا |
|-----|--------|
| **داخلی سیستم** | سفارش، اشتراک، افزونه، مشتری، فاکتور/کیفپول/مودیان/دانینگ، اعلان، پورت ADSL، سرور DCIM (`inventory.dc_server_*`)، فضای رک DCIM (`inventory.dc_space_*`)، تیکت پشتیبانی |
| **وبسرویس یکپارچه** | **شاهکار** (Compliance) — بیرونی |
| **وبسرویس HTTP** | API دلخواه + curl / JSON / form / multipart — شامل **شاهکار HTTP** و **NetBill HTTP** |
| **رویداد** | منتظر کالبک |
AAA دیگر بهصورت دستهٔ «یکپارچه — AAA / Provisioning» seed نمیشود؛ ایجاد/ویرایش کاربر AAA از **HTTP NetBill** (یا ماژول Provisioning محصول) انجام میشود.
Seed کاتالوگ: `WorkflowActionSeeder` (+ `ShahkarWorkflowActionSeeder` + `NetBillWorkflowActionSeeder`).
| موضوع | راهنما |
|--------|--------|
| شاهکار lifecycle + `service.type` | [shahkar-workflow-actions.md](./shahkar-workflow-actions.md) |
| استعلام Estelaam / Mobile | [shahkar-estelaam-api.md](./shahkar-estelaam-api.md) |
| NetBill V3.8 | [netbill-workflow-actions.md](./netbill-workflow-actions.md) |
| تست ADSL | [adsl-workflow-case-test.md](./adsl-workflow-case-test.md) |
| فروش سرور اختصاصی | [dedicated-sales-cartable.md](./dedicated-sales-cartable.md) |
| فروش پهنای باند اختصاصی | [dedicated-bandwidth-sales-cartable.md](./dedicated-bandwidth-sales-cartable.md) |
| فاکتور / پیشفاکتور روی دسته | [billing-document-mode.md](./billing-document-mode.md) |
| قیمت چنددورهای محصول | [product-cycle-pricing.md](./product-cycle-pricing.md) |
۱) تعریف عملیات
منو: **تنظیمات → وضعیتهای عملیاتی workflow** (تبهای بالا مثل پیکربندی سرورهای بیرونی)
| تب | محتوا |
|----|--------|
| **عملیات** | تعریف وضعیتهای عملیاتی |
| **دستهبندی** | گروهبندی همان عملیاتها |
دستهبندی
بدنه شاهکار از مشتری
برای عملیاتهای شاهکار (`shahkar_dynamic_body`): بدنه در اجرا از پروفایل مشتری و فیلدهای سفارش ساخته میشود.
در فرم، بلوک **«چه چیزی ارسال میشود؟»** فیلدهای دقیق همان متد را نشان میدهد (لیست کلی `{{…}}` مخفی است).
پارامترهای NetBill
برای `external_module_key=netbill` / `netbill_method`: پارامترهای query همان متد در جدول راهنما نمایش داده میشود؛ بدنه HTTP و لیست کلی متغیرها مخفی است.
متغیرهای قالب HTTP (عمومی)
در URL / هدر / بدنهٔ عملیاتهای HTTP غیردینامیک از `{{key}}` استفاده کنید:
| گروه | نمونه |
|------|--------|
| مشتری | `{{national_id}}` `{{first_name}}` `{{last_name}}` `{{father_name}}` `{{birth_date_ymd}}` `{{mobile}}` `{{email}}` |
| alias شاهکار | `{{identificationNo}}` `{{name}}` `{{family}}` `{{fatherName}}` `{{birthDate}}` `{{certificateNo}}` `{{requestId}}` |
| سفارش | `{{order_number}}` `{{order_total}}` `{{order_status}}` |
| سرویس | `{{subscription_number}}` `{{product_name}}` `{{username}}` `{{phone_line}}` |
| NetBill سرور | `{{netbill_webservice_url}}` `{{netbill_admin_id}}` |
| شاهکار سرور | `{{shahkar_authorization}}` |
آموزش هر عملیات
روی هر ردیف دکمهٔ **آموزش** (و داخل فرم ویرایش هم) توضیح میدهد:
دکمهٔ **آموزش کلی کاتالوگ** در فرم، راهنمای انواع عملیات (داخلی / HTTP / …) است.
۲) اتصال به وضعیت — داخل Workflow محصول
برای `subscription.terminate` / `activate` / `suspend` روی **سفارش جمعآوری یا تمدید**، اشتراک از `metadata.collection_subscription_id` (یا `renewal` / `addon_parent`) و `product_snapshot.subscription_id` خوانده میشود — نه لزوماً از `order_item_id` اشتراک جدید.
ارسال ایمیل و پیامک با وارد شدن به وضعیت
در همان تب **دپارتمانها و وضعیتها**، بخش **ارسال اعلان به مشتری** (زیر بخش عملیات وضعیت):
| فیلد | توضیح |
|------|--------|
| **ارسال ایمیل** | فعال/غیرفعال |
| **موضوع ایمیل** | موضوع ایمیل (جایگزینها استفاده میشوند) |
| **متن ایمیل** | متن HTML با ادیتور ساده (Bold, Italic, Link, List, H2/H3) |
| **ارسال پیامک** | فعال/غیرفعال |
| **متن پیامک** | متن ساده، حداکثر 500 کاراکتر |
**جایگزینهای قابل استفاده:**
**مثال:**
```
موضوع: سفارش {{order_number}} در مرحله {{status_name}}
متن ایمیل:
<p>{{customer_name}} عزیز،</p>
<p>سفارش شماره <strong>{{order_number}}</strong> برای محصول <strong>{{product_name}}</strong> در مرحله <strong>{{status_name}}</strong> قرار دارد.</p>
<p>دپارتمان مسئول: {{department_name}}</p>
متن پیامک:
سفارش {{order_number}} شما در مرحله {{status_name}} است.
```
اعلان بهصورت خودکار با ورود به وضعیت ارسال میشود (بدون نیاز به تنظیم عملیات جداگانه).
Provision روی سرور مقصد (همهٔ ماژولهای دارای provision)
| کلید | کار |
|------|-----|
| `subscription.terminate` / `suspend` / `resume` | فقط وضعیت اشتراک در **BSS** |
| `provisioning.terminate` | حذف اکانت روی پنل مقصد (cPanel / Hestia / ISPConfig / NetBill / …) |
| `provisioning.suspend` | تعلیق روی سرور مقصد |
| `provisioning.resume` | رفع تعلیق روی سرور مقصد |
این سه کلید برای هر اشتراکی که `provisioning_module` دارد (غیر از `manual`) کار میکنند؛ از همان مسیر resolve اشتراک کارتابل (فروش / تمدید / جمعآوری) استفاده میشود. Seed: `php artisan db:seed --class=Modules\\Order\\Database\\Seeders\\WorkflowActionSeeder`.
اگر اشتراکی ماژول Provision نداشته باشد (manual / خالی)، `provisioning.*` بهصورت **موفقِ ردشده** برمیگردد تا زنجیرهٔ کارتابل (مثلاً `subscription.terminate`) قطع نشود.
کارتابل جمعآوری مشترک (pipeline 7)
مسیر استاندارد دپارتمان «جمعآوری سرویس (سرور + BSS)» — Seeder: `CollectionWorkflowProvisionTerminateSeeder`:
فقط `subscription.terminate` کافی نیست: VM/اکانت روی سرور مقصد میماند.
۳) جریان اجرا
ورود به وضعیت → اجرای عملیات → موفق/شکست → (اختیاری) auto_next
دکمه **آموزش** در همین صفحات خلاصه را نشان میدهد.