hesabixCore/docs/accounting/DUPLICATE_CODE_ERROR_FIX.md

146 lines
4.9 KiB
Markdown
Raw Normal View History

2025-08-28 15:46:28 +03:30
# رفع خطای NonUniqueResultException در کدهای تکراری
## مشکل
خطای `NonUniqueResultException` با پیام "More than one result was found for query although one row or none was expected" در متد `app_accounting_remove_doc` رخ می‌دهد.
## علت
این خطا زمانی رخ می‌دهد که چندین سند حسابداری با کد یکسان در دیتابیس وجود دارد و متد `findOneBy` نمی‌تواند تصمیم بگیرد کدام سند را برگرداند.
## راه‌حل‌های پیاده‌سازی شده
### 1. بهبود متد `app_accounting_remove_doc`
#### تغییرات:
- **بررسی خودکار کدهای تکراری**: قبل از حذف سند، بررسی می‌شود که آیا کدهای تکراری وجود دارد
- **ترمیم خودکار**: در صورت وجود کدهای تکراری، سیستم خودکار آن‌ها را ترمیم می‌کند
- **پیدا کردن ایمن**: پس از ترمیم، سند به صورت ایمن پیدا می‌شود
#### کد جدید:
```php
// ابتدا بررسی کن که آیا کدهای تکراری وجود دارد
if ($provider->hasDuplicateCodes($request->headers->get('activeBid'), 'accounting')) {
// کدهای تکراری وجود دارد، ترمیم کن
$provider->fixDuplicateCodes($request->headers->get('activeBid'), 'accounting');
}
// حالا سند را پیدا کن
$doc = $entityManager->getRepository(HesabdariDoc::class)->findOneBy([
'code' => $params['code'],
'bid' => $request->headers->get('activeBid')
]);
```
### 2. متد جدید `hasDuplicateCodes`
#### عملکرد:
- بررسی وجود کدهای تکراری بدون ترمیم
- بازگشت `true` یا `false`
- قابل استفاده برای بررسی وضعیت قبل از عملیات
#### کد:
```php
public function hasDuplicateCodes($bid, $part = 'accounting')
{
// پیدا کردن کدهای تکراری
$qb = $repository->createQueryBuilder('e');
$qb->select('e.code, COUNT(e.id) as count')
->where('e.bid = :bid')
->setParameter('bid', $bid)
->groupBy('e.code')
->having('COUNT(e.id) > 1');
$duplicates = $qb->getQuery()->getResult();
return count($duplicates) > 0;
}
```
### 3. API جدید برای بررسی وضعیت
#### Endpoint: `/api/accounting/check-duplicate-codes`
- **Method**: GET
- **Access**: فقط ادمین
- **Function**: بررسی وجود کدهای تکراری
#### مثال استفاده:
```bash
GET /api/accounting/check-duplicate-codes?part=accounting
```
#### پاسخ:
```json
{
"result": 1,
"has_duplicates": true,
"message": "کدهای تکراری یافت شد"
}
```
## نحوه استفاده
### 1. بررسی وضعیت کدهای تکراری:
```bash
GET /api/accounting/check-duplicate-codes?part=accounting
```
### 2. ترمیم کدهای تکراری:
```bash
POST /api/accounting/fix-duplicate-codes
Content-Type: application/json
{
"part": "accounting"
}
```
### 3. حذف سند (خودکار ترمیم می‌کند):
```bash
POST /api/accounting/remove
Content-Type: application/json
{
"code": "1001"
}
```
## مزایای راه‌حل
1. **جلوگیری از خطا**: خطای `NonUniqueResultException` دیگر رخ نمی‌دهد
2. **ترمیم خودکار**: سیستم خودکار کدهای تکراری را ترمیم می‌کند
3. **بررسی وضعیت**: امکان بررسی وجود کدهای تکراری قبل از عملیات
4. **Backward Compatibility**: با کدهای موجود سازگار است
5. **امنیت**: فقط ادمین می‌تواند عملیات ترمیم را انجام دهد
## نکات مهم
1. **عملکرد خودکار**: حذف سند اکنون خودکار کدهای تکراری را ترمیم می‌کند
2. **بررسی قبل از عملیات**: می‌توانید وضعیت کدهای تکراری را بررسی کنید
3. **ترمیم انتخابی**: می‌توانید فقط کدهای تکراری را ترمیم کنید
4. **لاگ عملیات**: تمام عملیات ترمیم در لاگ ثبت می‌شود
5. **Backup**: قبل از ترمیم، از دیتابیس backup بگیرید
## تست
برای تست عملکرد:
1. **ایجاد کدهای تکراری** (در محیط تست):
```sql
UPDATE hesabdari_doc SET code = 1001 WHERE id IN (1, 2);
```
2. **بررسی وضعیت**:
```bash
GET /api/accounting/check-duplicate-codes
```
3. **حذف سند** (خودکار ترمیم می‌کند):
```bash
POST /api/accounting/remove
```
4. **بررسی مجدد**:
```bash
GET /api/accounting/check-duplicate-codes
```
این راه‌حل مشکل `NonUniqueResultException` را به طور کامل حل می‌کند و سیستم را در برابر کدهای تکراری محافظت می‌کند.