155 lines
4.7 KiB
Markdown
155 lines
4.7 KiB
Markdown
|
|
# پیدا کردن ایمن 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` را در تمام متدها حل میکند و سیستم را در برابر کدهای تکراری محافظت میکند.
|