/** * Create movement * * @param string $code HL7 event code * @param CSejour $sejour Admit * @param CAffectation $affectation Affectation * * @return CMovement|mixed */ function createMovement($code, CSejour $sejour, CAffectation $affectation = null) { $insert = in_array($code, CHL7v2SegmentZBE::$actions["INSERT"]); $update = in_array($code, CHL7v2SegmentZBE::$actions["UPDATE"]); $cancel = in_array($code, CHL7v2SegmentZBE::$actions["CANCEL"]); $movement = new CMovement(); // Initialise le mouvement $movement->sejour_id = $sejour->_id; $receiver = $sejour->_receiver; $configs = $receiver->_configs; $affectation_id = null; if ($affectation) { $current_log = $affectation->_ref_current_log; $first_affectation = $sejour->loadRefFirstAffectation(); /** @var CService $service */ $service = $affectation->loadRefService(); // Si le service est d'UHCD, de radiologie, d'urgence ou // Dans le cas où il s'agit de la première affectation du séjour et qu'on est en type "création" on ne recherche pas // un mouvement avec l'affectation, mais on va prendre le mouvement d'admission if ($service->uhcd || $service->radiologie || $service->urgence || $current_log && $current_log->type == "create" && $first_affectation && $first_affectation->_id == $affectation->_id) { switch ($configs["send_first_affectation"]) { case 'Z99': $affectation_id = $affectation->_id; $affectation = null; break; default: $movement->affectation_id = $affectation->_id; } } else { $movement->affectation_id = $affectation->_id; } } if ($insert) { // Dans le cas d'un insert le type correspond nécessairement au type actuel du séjour $movement->movement_type = $sejour->getMovementType($code); $movement->original_trigger_code = $code; $movement->start_of_movement = $this->getStartOfMovement($code, $sejour, $affectation); $movement->loadMatchingObject(); $movement->store(); return $sejour->_ref_hl7_movement = $movement; } elseif ($update) { // Dans le cas d'un update le type correspond à celui du trigger $movement_type = null; // Mise à jour entrée réelle if ($sejour->fieldModified("entree_reelle")) { $movement_type = "ADMI"; } // Mise à jour sortie réelle if ($sejour->fieldModified("sortie_reelle")) { $movement_type = "SORT"; } $movement->movement_type = $movement_type; // On ne recherche pas parmi les mouvements annulés $movement->cancel = 0; } $order = "affectation_id DESC"; $movements = $movement->loadMatchingList($order); if (!empty($movements)) { $movement = reset($movements); } if ($update) { if ($movement->original_trigger_code == "A02") { if (!$affectation) { $affectation = new CAffectation(); } $affectation->load($movement->affectation_id); } $movement->start_of_movement = $this->getStartOfMovement($movement->original_trigger_code, $sejour, $affectation, $movement); } // on annule un mouvement sauf dans le cas d'une annulation de mutation et que if ($cancel && !($code == "A12" && $movement->original_trigger_code != "A02")) { $movement->cancel = 1; } if ($affectation_id) { $movement->affectation_id = $affectation_id; } $movement->store(); return $sejour->_ref_hl7_movement = $movement; }
/** * Handle event A05 - pre-admit a patient * * @param CHL7Acknowledgment $ack Acknowledgment * @param CSejour $newVenue Admit * @param array $data Datas * * @return string */ function handleA05(CHL7Acknowledgment $ack, CSejour $newVenue, $data) { // Mapping venue - création possible $_modif_sejour = false; $exchange_hl7v2 = $this->_ref_exchange_hl7v2; $sender = $this->_ref_sender; $venueRI = CValue::read($data['admitIdentifiers'], "RI"); //$venueRISender = CValue::read($data['admitIdentifiers'], "RI_Sender"); $venueNPA = CValue::read($data['admitIdentifiers'], "NPA"); $venueVN = CValue::read($data['admitIdentifiers'], "VN"); $venueAN = $this->getVenueAN($sender, $data); $NDA = new CIdSante400(); $sender_purge_idex_movements = $sender->_configs["purge_idex_movements"]; if ($venueAN) { $NDA = CIdSante400::getMatch("CSejour", $sender->_tag_sejour, $venueAN); } // NDA non connu (non fourni ou non retrouvé) if (!$NDA->_id) { // Aucun NDA fourni / Association du NDA $code_NDA = !$venueAN ? "I225" : "I222"; $found = false; // NPA fourni if (!$found && $venueNPA) { $manage_npa = CMbArray::get($sender->_configs, "manage_npa"); if ($manage_npa) { $NPA = CIdSante400::getMatch("CSejour", $sender->_tag_sejour, $venueNPA); if ($NPA->_id) { $found = true; } $newVenue->load($NPA->object_id); // Mapping de la venue $this->mappingVenue($data, $newVenue); // Notifier les autres destinataires autre que le sender $newVenue->_eai_sender_guid = $sender->_guid; // On ne check pas la cohérence des dates des consults/intervs $newVenue->_skip_date_consistencies = true; if ($msgVenue = $newVenue->store()) { if ($newVenue->_collisions) { return $exchange_hl7v2->setAckAR($ack, "E213", $msgVenue, reset($newVenue->_collisions)); } return $exchange_hl7v2->setAckAR($ack, "E201", $msgVenue, $newVenue); } } else { /* @todo Gérer ce cas */ $venueRI = $venueNPA; } } // VN fourni if (!$found && $venueVN && !$sender_purge_idex_movements) { // Le champ PV1.2 conditionne le remplissage et l'interprétation de PV1.19 $this->getSejourByVisitNumber($newVenue, $data); if ($newVenue->_id) { $found = true; // Mapping du séjour $this->mappingVenue($data, $newVenue); // Notifier les autres destinataires autre que le sender $newVenue->_eai_sender_guid = $sender->_guid; // Pas de génération de NDA $newVenue->_generate_NDA = false; // On ne check pas la cohérence des dates des consults/intervs $newVenue->_skip_date_consistencies = true; if ($msgVenue = $newVenue->store()) { if ($newVenue->_collisions) { return $exchange_hl7v2->setAckAR($ack, "E213", $msgVenue, reset($newVenue->_collisions)); } return $exchange_hl7v2->setAckAR($ack, "E201", $msgVenue, $newVenue); } $code_NDA = "A222"; $_modif_sejour = true; } } // RI fourni if (!$found && $venueRI) { // Recherche du séjour par son RI if ($newVenue->load($venueRI)) { // Mapping du séjour $this->mappingVenue($data, $newVenue); // Le séjour retrouvé est-il différent que celui du message ? /* @todo voir comment faire (même patient, même praticien, même date ?) */ // Notifier les autres destinataires autre que le sender $newVenue->_eai_sender_guid = $sender->_guid; // Pas de génération de NDA $newVenue->_generate_NDA = false; // On ne check pas la cohérence des dates des consults/intervs $newVenue->_skip_date_consistencies = true; if ($msgVenue = $newVenue->store()) { if ($newVenue->_collisions) { return $exchange_hl7v2->setAckAR($ack, "E213", $msgVenue, reset($newVenue->_collisions)); } return $exchange_hl7v2->setAckAR($ack, "E201", $msgVenue, $newVenue); } $code_NDA = "I221"; $_modif_sejour = true; } else { $code_NDA = "I220"; } } if (!$newVenue->_id) { // Mapping du séjour $this->mappingVenue($data, $newVenue); // Séjour retrouvé ? if (CAppUI::conf("hl7 strictSejourMatch")) { // Recherche d'un num dossier déjà existant pour cette venue if ($newVenue->loadMatchingSejour(null, true, false)) { $code_NDA = "A221"; $_modif_sejour = true; } } else { // Valuer "entree" et "sortie" $newVenue->updatePlainFields(); $collision = $newVenue->getCollisions(); if (count($collision) == 1) { $newVenue = reset($collision); $code_NDA = "A222"; $_modif_sejour = true; } } // Mapping du séjour $newVenue = $this->mappingVenue($data, $newVenue); // Notifier les autres destinataires autre que le sender $newVenue->_eai_sender_guid = $sender->_guid; // Pas de génération de NDA $newVenue->_generate_NDA = false; // On ne check pas la cohérence des dates des consults/intervs $newVenue->_skip_date_consistencies = true; if ($msgVenue = $newVenue->store()) { if ($newVenue->_collisions) { return $exchange_hl7v2->setAckAR($ack, "E213", $msgVenue, reset($newVenue->_collisions)); } return $exchange_hl7v2->setAckAR($ack, "E201", $msgVenue, $newVenue); } } if ($msgNDA = CEAISejour::storeNDA($NDA, $newVenue, $sender)) { return $exchange_hl7v2->setAckAR($ack, "E202", $msgNDA, $newVenue); } if ($msgNRA = $this->getAlternateVisitID($data["PV1"], $newVenue)) { return $exchange_hl7v2->setAckAR($ack, "E214", $msgNRA, $newVenue); } // Création du VN, voir de l'objet if ($msgVN = $this->createObjectByVisitNumber($newVenue, $data)) { return $exchange_hl7v2->setAckAR($ack, "E210", $msgVN, $newVenue); } $codes = array($_modif_sejour ? "I202" : "I201", $code_NDA); $comment = CEAISejour::getComment($newVenue); $comment .= CEAISejour::getComment($NDA); } else { $newVenue->load($NDA->object_id); // Mapping de la venue $this->mappingVenue($data, $newVenue); // RI non fourni if (!$venueRI) { $code_NDA = "I223"; } else { $tmpVenue = new CSejour(); // RI connu if ($tmpVenue->load($venueRI)) { if ($tmpVenue->_id != $NDA->object_id) { $comment = "L'id source fait référence au séjour : {$NDA->object_id} et l'id cible au séjour : {$tmpVenue->_id}."; return $exchange_hl7v2->setAckAR($ack, "E230", $comment, $newVenue); } $code_NDA = "I224"; } else { $code_NDA = "A220"; } } // Notifier les autres destinataires autre que le sender $newVenue->_eai_sender_guid = $sender->_guid; // On ne check pas la cohérence des dates des consults/intervs $newVenue->_skip_date_consistencies = true; if ($msgVenue = $newVenue->store()) { if ($newVenue->_collisions) { return $exchange_hl7v2->setAckAR($ack, "E213", $msgVenue, reset($newVenue->_collisions)); } return $exchange_hl7v2->setAckAR($ack, "E201", $msgVenue, $newVenue); } // Création du VN, voir de l'objet if ($msgVN = $this->createObjectByVisitNumber($newVenue, $data)) { return $exchange_hl7v2->setAckAR($ack, "E210", $msgVN, $newVenue); } $codes = array("I202", $code_NDA); $comment = CEAISejour::getComment($newVenue); } // Mapping du mouvement if ($sender_purge_idex_movements) { // On recherche un mouvement de l'event (A05/A01/A04) $movement = new CMovement(); $movement->sejour_id = $newVenue->_id; $movement->original_trigger_code = $this->_ref_exchange_hl7v2->code; $movement->cancel = 0; $movement->loadMatchingObject(); // Si on a un mouvement alors on annule tous les autres if ($movement->_id) { foreach ($newVenue->loadRefsMovements() as $_movement) { // On passe en trash l'idex associé $_movement->loadLastId400(); $last_id400 = $_movement->_ref_last_id400; if ($last_id400->_id) { $last_id400->tag = "trash_" . $last_id400->tag; $last_id400->last_update = CMbDT::dateTime(); $last_id400->_eai_sender_guid = $sender->_guid; $last_id400->store(); } // On annule le mouvement $_movement->cancel = 1; $_movement->_eai_sender_guid = $sender->_guid; $_movement->store(); } } } $return_movement = $this->mapAndStoreMovement($ack, $newVenue, $data); if (is_string($return_movement)) { return $return_movement; } $movement = $return_movement; // Mapping de l'affectation $return_affectation = $this->mapAndStoreAffectation($newVenue, $data, $return_movement); if (is_string($return_affectation)) { return $exchange_hl7v2->setAckAR($ack, "E208", $return_affectation, $newVenue); } $affectation = $return_affectation; // Affectation de l'affectation au mouvement if ($movement && $affectation && $affectation->_id) { $movement->affectation_id = $affectation->_id; $movement->_eai_sender_guid = $sender->_guid; $movement->store(); } // Dans le cas d'une grossesse if ($return_grossesse = $this->storeGrossesse($newVenue)) { return $exchange_hl7v2->setAckAR($ack, "E211", $return_grossesse, $newVenue); } // Dans le cas d'une naissance if ($return_naissance = $this->mapAndStoreNaissance($newVenue, $data)) { return $exchange_hl7v2->setAckAR($ack, "E212", $return_naissance, $newVenue); } return $exchange_hl7v2->setAckAA($ack, $codes, $comment, $newVenue); }