feat(resource): expose each offering's service section

The resource booking modal groups services under their section, the way the
doctor's service booking does. The offering list had no section, so the list
could only be flat.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
hamed
2026-08-03 13:47:39 +03:30
co-authored by Claude Opus 5
parent dc728acaaf
commit 1543eddd9e
3 changed files with 45 additions and 0 deletions
+17
View File
@@ -186,6 +186,23 @@
| `attributes` | object | — | حداکثر ۲۰ کلید · کلید `[a-z_]{1,40}` · مقدار فقط اسکالر |
| `active` | bool | — | پیش‌فرض `true` |
### `service_section` روی فهرست سرویس‌های منبع (2026-08)
`GET /api/v1/resource/{uuid}/services` برای هر سرویس `service_section` را هم می‌دهد
(`{uuid, name}`). مودالِ رزرو منبع سرویس‌ها را زیر بخششان گروه می‌کند — مثل نوبت‌دهی
سرویسیِ پزشک — و بدون این فیلد فهرست یک لیستِ تختِ بی‌دسته می‌شد.
خروجی واقعی:
```json
{
"service_name": "لیزر زیربغل",
"service_section": { "uuid": "9eac29e4-…", "name": "خدمات لیزر و زیبایی" },
"effective_duration_minutes": 20,
"active": true
}
```
### پزشک ناظر (2026-08)
هر منبع **الزاماً** زیر نظر یک پزشک است؛ صفحهٔ نوبت‌ها تب منابع را زیر همان پزشک
@@ -47,6 +47,12 @@ final class ResourceServiceAssignmentService
'effective_price_rials' => $spec->priceRials,
'duration_source' => $spec->durationSource,
'price_source' => $spec->priceSource,
// مودالِ رزرو منبع سرویس‌ها را زیر بخششان گروه می‌کند؛ بدون این، فهرست
// یک لیست تختِ بی‌دسته می‌شد.
'service_section' => [
'uuid' => $item->getSection()->getUuid(),
'name' => $item->getSection()->getName(),
],
];
}
@@ -159,4 +159,26 @@ class ResourceServiceOfferingTest extends ResourceTestCase
self::assertSame([], $repo->activeResourceIdsFor($service));
self::assertSame(25, $repo->findOneFor($resource, $service)?->getDurationMinutes());
}
/** مودال رزرو منبع سرویس‌ها را زیر بخششان گروه می‌کند، پس فهرست باید بخش را بدهد. */
public function testOfferingListCarriesTheServiceSection(): void
{
[$user, , $address] = $this->clinicWithAddress();
$resource = $this->resource($address, $this->resourceType($address), 'لیزر الکساندرایت');
$service = $this->service($address, 'لیزر زیربغل');
$this->authJson('PUT', "/api/v1/resource/{$resource->getUuid()}/services", $user, [
'services' => [['service_uuid' => $service->getUuid()]],
]);
self::assertSame(200, $this->responseCode());
$body = $this->authJson('GET', "/api/v1/resource/{$resource->getUuid()}/services", $user);
self::assertSame(200, $this->responseCode());
self::assertSame(
$service->getSection()->getUuid(),
$body['data'][0]['service_section']['uuid'],
);
self::assertSame('بخش لیزر زیربغل', $body['data'][0]['service_section']['name']);
}
}