# رفع خطای 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` را به طور کامل حل می‌کند و سیستم را در برابر کدهای تکراری محافظت می‌کند.