hesabixCore/docs/accounting/DUPLICATE_CODE_ERROR_FIX.md

4.9 KiB

رفع خطای 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

تغییرات:

  • بررسی خودکار کدهای تکراری: قبل از حذف سند، بررسی می‌شود که آیا کدهای تکراری وجود دارد
  • ترمیم خودکار: در صورت وجود کدهای تکراری، سیستم خودکار آن‌ها را ترمیم می‌کند
  • پیدا کردن ایمن: پس از ترمیم، سند به صورت ایمن پیدا می‌شود

کد جدید:

// ابتدا بررسی کن که آیا کدهای تکراری وجود دارد
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
  • قابل استفاده برای بررسی وضعیت قبل از عملیات

کد:

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: بررسی وجود کدهای تکراری

مثال استفاده:

GET /api/accounting/check-duplicate-codes?part=accounting

پاسخ:

{
    "result": 1,
    "has_duplicates": true,
    "message": "کدهای تکراری یافت شد"
}

نحوه استفاده

1. بررسی وضعیت کدهای تکراری:

GET /api/accounting/check-duplicate-codes?part=accounting

2. ترمیم کدهای تکراری:

POST /api/accounting/fix-duplicate-codes
Content-Type: application/json

{
    "part": "accounting"
}

3. حذف سند (خودکار ترمیم می‌کند):

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. ایجاد کدهای تکراری (در محیط تست):
UPDATE hesabdari_doc SET code = 1001 WHERE id IN (1, 2);
  1. بررسی وضعیت:
GET /api/accounting/check-duplicate-codes
  1. حذف سند (خودکار ترمیم می‌کند):
POST /api/accounting/remove
  1. بررسی مجدد:
GET /api/accounting/check-duplicate-codes

این راه‌حل مشکل NonUniqueResultException را به طور کامل حل می‌کند و سیستم را در برابر کدهای تکراری محافظت می‌کند.