102 lines
4.6 KiB
PHP
102 lines
4.6 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace app\common\service\pharmacy;
|
|
|
|
use DomainException;
|
|
use InvalidArgumentException;
|
|
|
|
final class EjPharmacyPayload
|
|
{
|
|
/**
|
|
* @param array<string,mixed> $order
|
|
* @param array<string,mixed> $prescription
|
|
* @param array<int,string> $medicineMappings
|
|
* @return array<string,mixed>
|
|
*/
|
|
public static function build(array $order, array $prescription, array $medicineMappings, int $revision): array
|
|
{
|
|
$orderNo = trim((string) ($order['order_no'] ?? ''));
|
|
if ($orderNo === '') {
|
|
throw new InvalidArgumentException('order_no is required');
|
|
}
|
|
$herbs = $prescription['herbs'] ?? [];
|
|
if (!is_array($herbs) || $herbs === []) {
|
|
throw new InvalidArgumentException('prescription herbs are required');
|
|
}
|
|
$medicines = [];
|
|
foreach ($herbs as $herb) {
|
|
if (!is_array($herb)) {
|
|
continue;
|
|
}
|
|
$medicineId = (int) ($herb['medicine_id'] ?? $herb['id'] ?? 0);
|
|
$name = trim((string) ($herb['name'] ?? $herb['title'] ?? ''));
|
|
$medicineCode = trim((string) ($medicineMappings[$medicineId] ?? ''));
|
|
if ($medicineId <= 0 || $medicineCode === '') {
|
|
throw new DomainException('Unmapped medicine: ' . ($name !== '' ? $name : (string) $medicineId));
|
|
}
|
|
$quantity = (float) ($herb['dose'] ?? $herb['dosage'] ?? $herb['quantity'] ?? 0);
|
|
if ($quantity <= 0) {
|
|
throw new InvalidArgumentException('Medicine quantity must be positive: ' . $name);
|
|
}
|
|
$medicines[] = [
|
|
'source_medicine_id' => (string) $medicineId,
|
|
'medicine_code' => $medicineCode,
|
|
'name' => $name,
|
|
'quantity' => number_format($quantity, 4, '.', ''),
|
|
'unit' => trim((string) ($herb['unit'] ?? '克')) ?: '克',
|
|
'usage' => trim((string) ($herb['usage'] ?? '')),
|
|
];
|
|
}
|
|
if ($medicines === []) {
|
|
throw new InvalidArgumentException('prescription herbs are required');
|
|
}
|
|
|
|
return [
|
|
'source_system' => 'zyt',
|
|
'source_order_no' => $orderNo,
|
|
'source_revision' => max($revision, 1),
|
|
'patient' => [
|
|
'source_patient_id' => (string) ($prescription['patient_id'] ?? ''),
|
|
'name' => trim((string) ($prescription['patient_name'] ?? $order['recipient_name'] ?? '')),
|
|
'id_card' => trim((string) ($prescription['id_card'] ?? '')),
|
|
'mobile' => trim((string) ($prescription['phone'] ?? $order['recipient_phone'] ?? '')),
|
|
],
|
|
'shipping' => [
|
|
'recipient_name' => trim((string) ($order['recipient_name'] ?? $prescription['patient_name'] ?? '')),
|
|
'recipient_mobile' => trim((string) ($order['recipient_phone'] ?? $prescription['phone'] ?? '')),
|
|
'province' => trim((string) ($order['shipping_province'] ?? '')),
|
|
'city' => trim((string) ($order['shipping_city'] ?? '')),
|
|
'district' => trim((string) ($order['shipping_district'] ?? '')),
|
|
'address' => trim((string) ($order['shipping_address'] ?? '')),
|
|
],
|
|
'prescription' => [
|
|
'source_prescription_id' => (string) ($prescription['id'] ?? ''),
|
|
'diagnosis' => trim((string) (
|
|
$prescription['clinical_diagnosis']
|
|
?? $prescription['diagnosis']
|
|
?? $prescription['diagnosis_name']
|
|
?? ''
|
|
)),
|
|
'processing_type' => trim((string) ($prescription['processing_type'] ?? 'decoction')) ?: 'decoction',
|
|
'dose_count' => max((int) ($order['dose_count'] ?? $prescription['dose_count'] ?? 1), 1),
|
|
'doctor' => [
|
|
'source_doctor_id' => (string) ($prescription['creator_id'] ?? $prescription['doctor_id'] ?? ''),
|
|
'name' => trim((string) ($prescription['doctor_name'] ?? '')),
|
|
],
|
|
'doctor_signature' => is_array($prescription['doctor_signature'] ?? null)
|
|
? $prescription['doctor_signature']
|
|
: [],
|
|
'medicines' => $medicines,
|
|
'instructions' => trim((string) (
|
|
$prescription['usage_instruction']
|
|
?? $prescription['instructions']
|
|
?? $prescription['advice']
|
|
?? ''
|
|
)),
|
|
],
|
|
];
|
|
}
|
|
}
|