hesabixCore/docs/accounting/SAFE_ENTITY_FINDING.md

155 lines
4.7 KiB
Markdown
Raw Permalink Normal View History

2025-08-28 15:46:28 +03:30
# پیدا کردن ایمن 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` را در تمام متدها حل می‌کند و سیستم را در برابر کدهای تکراری محافظت می‌کند.