$order * @param array $prescription * @param array $medicineMappings * @return array */ 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'] ?? '' )), ], ]; } }