Add tests and implementation for ServiceDetailPage and PriceInput components

- Implement PriceInput component tests to validate Persian and Arabic numeral handling, input formatting, and controlled behavior.
- Create ServiceDetailPage component with detailed service information, including pricing, insurance coverage, and editing capabilities.
- Add API tests for service item detail retrieval and coverage synchronization with insurance contracts.
- Ensure proper error handling and user feedback for service item retrieval and coverage management.
This commit is contained in:
hamed
2026-07-18 12:10:49 +03:30
parent f1d58e1604
commit 42d9ad26c5
27 changed files with 1758 additions and 284 deletions
@@ -27,6 +27,17 @@ class TenantServiceCoverageRepository extends ServiceEntityRepository
return $this->findBy(['tenantInsuranceId' => $tenantInsuranceId]);
}
/** آیا این خدمت زیر هر قرارداد بیمه‌ای پوشش فعال دارد؟ */
public function hasActiveCoverage(int $serviceItemId): bool
{
return (int) $this->createQueryBuilder('c')
->select('COUNT(c.id)')
->where('c.serviceItemId = :item AND c.covered = true')
->setParameter('item', $serviceItemId)
->getQuery()
->getSingleScalarResult() > 0;
}
public function save(TenantServiceCoverage $entity, bool $flush = true): void
{
$this->getEntityManager()->persist($entity);
@@ -162,5 +162,23 @@ class TenantInsuranceService
->setCeilingRials($ceilingRials);
$this->coverageRepo->save($override);
$this->syncServiceItemInsuranceFlag($serviceItemId);
}
/**
* پرچم insurance_covered خدمت را با پوشش‌های واقعی هم‌تراز می‌کند. پنل دیگر این
* پرچم را دستی نمی‌گیرد؛ تنها منبع حقیقت، ردیف‌های پوشش قراردادهای بیمه است.
*/
private function syncServiceItemInsuranceFlag(int $serviceItemId): void
{
$serviceItem = $this->serviceItemRepo->find($serviceItemId);
if ($serviceItem === null) {
return;
}
$covered = $this->coverageRepo->hasActiveCoverage($serviceItemId);
if ($serviceItem->isInsuranceCovered() !== $covered) {
$this->serviceItemRepo->save($serviceItem->setInsuranceCovered($covered));
}
}
}