# POST /v2/account-history/calculate-monthly

<div id="bkmrk-" style="direction: rtl; font-family: Vazir, Tahoma; line-height: 1.85; text-align: justify;">  </div>### Route Info

<div id="bkmrk-method-endpoint-cont" style="direction: rtl; font-family: Vazir, Tahoma; line-height: 1.85; text-align: justify;"><table border="1" style="width: 100%; border-collapse: collapse; text-align: center;"><tbody><tr style="background: #f5f5f5; font-weight: bold;"><td>Method</td><td>Endpoint</td><td>Controller</td><td>Middleware</td></tr><tr><td>POST</td><td>/v2/account-history/calculate-monthly</td><td>AccountHistoryController@calculateMonthlyBalanceForYear</td><td>authWithJwt</td></tr></tbody></table>

  </div>### شرح عملکرد (Functionality)

این API وظیفه **محاسبه و ذخیره مانده‌های ماهانه** برای یک همکار (Colleague) را دارد. محاسبه می‌تواند بر اساس:

<div id="bkmrk-%DB%8C%DA%A9-%D8%B3%D8%A7%D9%84-%D9%85%D8%B4%D8%AE%D8%B5-%28%D9%85%D8%AB%D9%84%D8%A7%D9%8B-1" style="direction: rtl; font-family: Vazir, Tahoma; line-height: 1.85; text-align: justify;">- یک سال مشخص (مثلاً 1402)
- یا یک بازه تاریخ دلخواه (from / to)

</div>محاسبات می‌توانند به صورت:

<div id="bkmrk-%D9%87%D9%85%D8%B2%D9%85%D8%A7%D9%86-%28sync%29%3A-%D8%AE%D8%B1%D9%88%D8%AC%DB%8C" style="direction: rtl; font-family: Vazir, Tahoma; line-height: 1.85; text-align: justify;">- **همزمان (Sync)**: خروجی محاسبه همان لحظه بازگردانده می‌شود.
- **غیرهمزمان (Async)**: پردازش در صف اجرا شده و پاسخ سریع برمی‌گردد.

</div>در حالت async، عملیات توسط `CalculateAccountHistoryJob` با type = "monthly" انجام می‌شود.

<div id="bkmrk--1" style="direction: rtl; font-family: Vazir, Tahoma; line-height: 1.85; text-align: justify;">  </div>### ورودی (Request Body)

```
{
  "colleague_id": 108,
  "year": 1403,           // optional
  "from": "1403-01-01",   // optional
  "to": "1403-12-29",     // optional
  "async": false          // optional (default=false)
}
```

#### قوانین اعتبارسنجی

<div id="bkmrk-colleague_id-%D8%A7%D9%84%D8%B2%D8%A7%D9%85%DB%8C-" style="direction: rtl; font-family: Vazir, Tahoma; line-height: 1.85; text-align: justify;">- **colleague\_id** الزامی و باید در جدول colleagues وجود داشته باشد.
- **year** اختیاری و باید بین 1300 تا 1500 باشد.
- **from/to** تاریخ شمسی معتبر در فرمت `Y-m-d`.
- **async** مقدار boolean.
- ارسال تاریخ آینده ممنوع است → خطای **FUTURE\_DATE\_NOT\_ALLOWED**.

  </div>### منطق اجرا (Execution Logic)

<div id="bkmrk-%D8%A7%D8%B9%D8%AA%D8%A8%D8%A7%D8%B1%D8%B3%D9%86%D8%AC%DB%8C-laravel-%D8%A7" style="direction: rtl; font-family: Vazir, Tahoma; line-height: 1.85; text-align: justify;">- اعتبارسنجی Laravel اجرا می‌شود.
- اگر from یا to بزرگ‌تر از تاریخ امروز باشد → خطا.
- اگر async=true: 
    - Job با مقادیر: 
        - colleague\_id
        - year
        - type = monthly
        
        Dispatch می‌شود.
    - پاسخ سریع با وضعیت **queued** برمی‌گردد.
- اگر async=false:   
    محاسبه مستقیم با: `calculateAndStoreMonthlyBalance()` انجام می‌شود.

</div>#### مشخصات Job

<div id="bkmrk-timeout%3A-3600-%D8%AB%D8%A7%D9%86%DB%8C%D9%87-" style="direction: rtl; font-family: Vazir, Tahoma; line-height: 1.85; text-align: justify;">- **timeout:** 3600 ثانیه
- **tries:** 3
- در صورت خطا → fail شدن job
- ثبت کامل لاگ از شروع، پایان یا خطا

  </div>### پاسخ موفق (Async Mode)

```
{
  "payload": null,
  "meta": {
    "colleague_id": 108,
    "year": 1403,
    "from": "1403-01-01",
    "to": "1403-12-29",
    "type": "monthly",
    "status": "queued",
    "timestamp": "2025-12-01T12:35:00+03:30"
  }
}
```

<div id="bkmrk--2" style="direction: rtl; font-family: Vazir, Tahoma; line-height: 1.85; text-align: justify;">  </div>### پاسخ موفق (Sync Mode)

```
{
  "payload": {
    "1403-01": { "credit": 0, "debit": 900000, "balance": -900000 },
    "1403-02": { "credit": 500000, "debit": 0, "balance": 500000 }
  },
  "meta": {
    "colleague_id": 108,
    "year": 1403,
    "total_months": 12,
    "timestamp": "2025-12-01T12:35:00+03:30"
  }
}
```

<div id="bkmrk--3" style="direction: rtl; font-family: Vazir, Tahoma; line-height: 1.85; text-align: justify;">  </div>### پاسخ‌های خطا (Error Responses)

#### اعتبارسنجی (400)

```
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "colleague_id field is required"
  },
  "meta": {
    "timestamp": "2025-12-01T12:40:00+03:30"
  }
}
```

#### تاریخ آینده مجاز نیست (400)

```
{
  "error": {
    "code": "FUTURE_DATE_NOT_ALLOWED",
    "message": "Cannot calculate for future dates."
  },
  "meta": {
    "colleague_id": 108,
    "to": "1405-01-01",
    "timestamp": "2025-12-01T12:40:00+03:30"
  }
}
```

#### خطای داخلی (500)

```
{
  "error": {
    "code": "INTERNAL_ERROR",
    "message": "Unexpected error..."
  },
  "meta": {
    "colleague_id": 108,
    "timestamp": "2025-12-01T12:41:00+03:30"
  }
}
```

<div id="bkmrk--4" style="direction: rtl; font-family: Vazir, Tahoma; line-height: 1.85; text-align: justify;">  </div>### Meta

<div id="bkmrk-job-class%3A-calculate" style="direction: rtl; font-family: Vazir, Tahoma; line-height: 1.85; text-align: justify;">- Job Class: `CalculateAccountHistoryJob`
- Service Method: `calculateAndStoreMonthlyBalance`
- Job Type: `monthly`

</div>