# پیدا کردن ایمن Entity ها با بررسی کدهای تکراری ## مشکل خطای `NonUniqueResultException` در متدهای مختلف که از `findOneBy` استفاده می‌کنند رخ می‌دهد. ## راه‌حل‌های پیاده‌سازی شده ### 1. متد `findHesabdariDocSafely` #### عملکرد: - بررسی خودکار کدهای تکراری قبل از پیدا کردن سند - ترمیم خودکار کدهای تکراری در صورت نیاز - پیدا کردن ایمن سند حسابداری #### استفاده: ```php $doc = $provider->findHesabdariDocSafely($entityManager, [ 'bid' => $acc['bid'], 'year' => $acc['year'], 'code' => $params['code'], 'money' => $acc['money'] ]); ``` ### 2. متد `findEntitySafely` (عمومی) #### عملکرد: - بررسی خودکار کدهای تکراری برای هر نوع entity - ترمیم خودکار در صورت نیاز - قابل استفاده برای تمام entity ها #### استفاده: ```php // برای سند حسابداری $doc = $provider->findEntitySafely($entityManager, HesabdariDoc::class, [ 'bid' => $acc['bid'], 'code' => $params['code'] ], 'accounting'); // برای شخص $person = $provider->findEntitySafely($entityManager, Person::class, [ 'bid' => $acc['bid'], 'code' => $params['code'] ], 'person'); // برای حساب بانکی $bank = $provider->findEntitySafely($entityManager, BankAccount::class, [ 'bid' => $acc['bid'], 'code' => $params['code'] ], 'bank'); ``` ## متدهای بهبود یافته ### 1. `app_accounting_doc_get` ```php // قبل از بهبود $doc = $entityManager->getRepository(HesabdariDoc::class)->findOneBy([ 'bid' => $acc['bid'], 'year' => $acc['year'], 'code' => $params['code'], 'money' => $acc['money'] ]); // بعد از بهبود $doc = $provider->findHesabdariDocSafely($entityManager, [ 'bid' => $acc['bid'], 'year' => $acc['year'], 'code' => $params['code'], 'money' => $acc['money'] ]); ``` ### 2. `app_accounting_remove_doc` ```php // قبل از بهبود $doc = $entityManager->getRepository(HesabdariDoc::class)->findOneBy([ 'code' => $params['code'], 'bid' => $request->headers->get('activeBid') ]); // بعد از بهبود $doc = $provider->findHesabdariDocSafely($entityManager, [ 'code' => $params['code'], 'bid' => $request->headers->get('activeBid') ]); ``` ## مزایای راه‌حل 1. **جلوگیری از خطا**: خطای `NonUniqueResultException` دیگر رخ نمی‌دهد 2. **ترمیم خودکار**: کدهای تکراری خودکار ترمیم می‌شوند 3. **قابلیت استفاده مجدد**: متدهای عمومی قابل استفاده در تمام بخش‌ها 4. **Backward Compatibility**: با کدهای موجود سازگار است 5. **عملکرد بهینه**: فقط در صورت نیاز ترمیم انجام می‌شود ## نحوه استفاده در سایر کنترلرها ### برای کنترلر Person: ```php // قبل $person = $entityManager->getRepository(Person::class)->findOneBy([ 'bid' => $acc['bid'], 'code' => $params['code'] ]); // بعد $person = $provider->findEntitySafely($entityManager, Person::class, [ 'bid' => $acc['bid'], 'code' => $params['code'] ], 'person'); ``` ### برای کنترلر Bank: ```php // قبل $bank = $entityManager->getRepository(BankAccount::class)->findOneBy([ 'bid' => $acc['bid'], 'code' => $params['code'] ]); // بعد $bank = $provider->findEntitySafely($entityManager, BankAccount::class, [ 'bid' => $acc['bid'], 'code' => $params['code'] ], 'bank'); ``` ## نکات مهم 1. **پارامتر part**: برای entity هایی که کد دارند، part را مشخص کنید 2. **عملکرد خودکار**: ترمیم فقط در صورت وجود کدهای تکراری انجام می‌شود 3. **امنیت**: تمام عملیات در تراکنش انجام می‌شود 4. **لاگ**: عملیات ترمیم در لاگ ثبت می‌شود 5. **Backup**: قبل از استفاده، از دیتابیس backup بگیرید ## تست برای تست عملکرد: ```php // تست پیدا کردن ایمن $doc = $provider->findHesabdariDocSafely($entityManager, [ 'bid' => $bid, 'code' => '1001' ]); // تست پیدا کردن عمومی $person = $provider->findEntitySafely($entityManager, Person::class, [ 'bid' => $bid, 'code' => 'P001' ], 'person'); ``` این راه‌حل مشکل `NonUniqueResultException` را در تمام متدها حل می‌کند و سیستم را در برابر کدهای تکراری محافظت می‌کند.