/**
  * Mapping et enregistrement de la venue
  *
  * @param CHL7Acknowledgment $ack      Acknowledgment
  * @param CSejour            $newVenue Admit
  * @param array              $data     Datas
  *
  * @return string
  */
 function mapAndStoreVenue(CHL7Acknowledgment $ack, CSejour $newVenue, $data)
 {
     $exchange_hl7v2 = $this->_ref_exchange_hl7v2;
     $sender = $this->_ref_sender;
     $event_code = $exchange_hl7v2->code;
     // Mapping du séjour
     $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;
     // On ne synchronise pas le séjour pour une modification dans un premier temps pour traiter le mouvement
     if ($event_code == "Z99") {
         $newVenue->_no_synchro = true;
     }
     if ($msgVenue = $newVenue->store()) {
         return $exchange_hl7v2->setAckAR($ack, "E201", $msgVenue, $newVenue);
     }
     // Mapping du mouvement
     $return_movement = $this->mapAndStoreMovement($ack, $newVenue, $data);
     if (is_string($return_movement)) {
         return $return_movement;
     }
     $movement = $return_movement;
     // On re-synchronise le séjour ayant subi une modification
     if ($event_code == "Z99") {
         // Est-ce que le mouvement est bien le dernier ?
         // On prend ceux qui ne sont pas annulés
         $where["cancel"] = " = '0'";
         $newVenue->loadRefsMovements($where);
         if ($newVenue->_ref_last_movement->_id == $movement->_id) {
             // on affecte le praticien
             $newVenue->praticien_id = $this->_doctor_id;
             // 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;
             // On réactive la synchro
             $newVenue->_no_synchro = false;
             if ($msgVenue = $newVenue->store()) {
                 return $exchange_hl7v2->setAckAR($ack, "E201", $msgVenue, $newVenue);
             }
         }
     }
     // Mapping de l'affectation
     $return_affectation = $this->mapAndStoreAffectation($newVenue, $data, $movement);
     if (is_string($return_affectation)) {
         return $exchange_hl7v2->setAckAR($ack, "E208", $return_affectation, $newVenue);
     }
     $affectation = $return_affectation;
     // Attribution de l'affectation au mouvement
     if ($movement && $affectation && $affectation->_id) {
         $movement->affectation_id = $affectation->_id;
         $movement->_eai_sender_guid = $sender->_guid;
         $movement->store();
         //if ($msg = $movement->store()) {
         //  return $exchange_hl7v2->setAckAR($ack, "E208", $msg, $newVenue);
         //}
     }
     // Dans le cas d'une grossesse
     if ($return_grossesse = $this->storeGrossesse($newVenue)) {
         return $exchange_hl7v2->setAckAR($ack, "E211", $return_grossesse, $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", "I226");
     $comment = CEAISejour::getComment($newVenue);
     return $exchange_hl7v2->setAckAA($ack, $codes, $comment, $newVenue);
 }
 /**
  * Record admit
  *
  * @param CHPrimXMLAcquittementsPatients $dom_acq    Acquittement
  * @param CPatient                       $newPatient Patient
  * @param array                          $data       Data
  * @param CSejour                        &$newVenue  Admit
  *
  * @return CHPrimXMLAcquittementsPatients $msgAcq 
  **/
 function venuePatient(CHPrimXMLAcquittementsPatients $dom_acq, CPatient $newPatient, $data, &$newVenue = null)
 {
     $echg_hprim = $this->_ref_echange_hprim;
     // Cas 1 : Traitement du patient
     $domEnregistrementPatient = new CHPrimXMLEnregistrementPatient();
     $domEnregistrementPatient->_ref_echange_hprim = $echg_hprim;
     $msgAcq = $domEnregistrementPatient->enregistrementPatient($dom_acq, $newPatient, $data);
     if ($echg_hprim->statut_acquittement != "OK") {
         return $msgAcq;
     }
     // Cas 2 : Traitement de la venue
     $dom_acq = new CHPrimXMLAcquittementsPatients();
     $dom_acq->_identifiant_acquitte = $data['identifiantMessage'];
     $dom_acq->_sous_type_evt = $this->sous_type;
     $dom_acq->_ref_echange_hprim = $echg_hprim;
     // Traitement du message des erreurs
     $avertissement = $msgID400 = $msgVenue = $msgNDA = "";
     $_code_Venue = $_code_NumDos = $_num_dos_create = $_modif_venue = false;
     $sender = $echg_hprim->_ref_sender;
     $sender->loadConfigValues();
     $this->_ref_sender = $sender;
     $idSourceVenue = $data['idSourceVenue'];
     $idCibleVenue = $data['idCibleVenue'];
     if (!$newVenue) {
         $newVenue = new CSejour();
     }
     // Cas d'une annulation
     $cancel = false;
     if ($data['action'] == "suppression") {
         $cancel = true;
     }
     // Affectation du patient
     $newVenue->patient_id = $newPatient->_id;
     // Affectation de l'établissement
     $newVenue->group_id = $sender->group_id;
     $commentaire = "";
     $codes = array();
     // Si CIP
     if (!CAppUI::conf('smp server')) {
         // Acquittement d'erreur : identifiants source et cible non fournis pour le patient / venue
         if (!$idSourceVenue && !$idCibleVenue) {
             return $echg_hprim->setAckError($dom_acq, "E100", $commentaire, $newVenue);
         }
         $nda = CIdSante400::getMatch("CSejour", $sender->_tag_sejour, $idSourceVenue);
         // idSource non connu
         if (!$nda->_id) {
             // idCible fourni
             if ($idCibleVenue) {
                 if ($newVenue->load($idCibleVenue)) {
                     // Dans le cas d'une annulation de la venue
                     if ($cancel) {
                         if ($msgAcq = $this->doNotCancelVenue($newVenue, $dom_acq, $echg_hprim)) {
                             return $msgAcq;
                         }
                     }
                     // Recherche d'un num dossier déjà existant pour cette venue
                     // Mise en trash du numéro de dossier reçu
                     $newVenue->loadNDA();
                     if ($this->trashNDA($newVenue, $sender)) {
                         $nda->_trash = true;
                     } else {
                         // Mapping du séjour si pas de numéro de dossier
                         $newVenue = $this->mappingVenue($data['venue'], $newVenue, $cancel);
                         $msgVenue = CEAISejour::storeSejour($newVenue, $sender);
                         $commentaire = CEAISejour::getComment($newVenue);
                         $_code_NumDos = "I121";
                         $_code_Venue = true;
                     }
                 } else {
                     $_code_NumDos = "I120";
                 }
             } else {
                 $_code_NumDos = "I122";
             }
             if (!$newVenue->_id) {
                 // Mapping du séjour
                 $newVenue->_NDA = $nda->id400;
                 $newVenue = $this->mappingVenue($data['venue'], $newVenue, $cancel);
                 // Séjour retrouvé
                 if (CAppUI::conf("hprimxml strictSejourMatch")) {
                     if ($newVenue->loadMatchingSejour(null, true, $sender->_configs["use_sortie_matching"])) {
                         // Dans le cas d'une annulation de la venue
                         if ($cancel) {
                             if ($msgAcq = $this->doNotCancelVenue($newVenue, $dom_acq, $echg_hprim)) {
                                 return $msgAcq;
                             }
                         }
                         // Recherche d'un num dossier déjà existant pour cette venue
                         // Mise en trash du numéro de dossier reçu
                         $newVenue->loadNDA();
                         if ($this->trashNDA($newVenue, $sender)) {
                             $nda->_trash = true;
                         } else {
                             // Mapping du séjour
                             $newVenue = $this->mappingVenue($data['venue'], $newVenue, $cancel);
                             $msgVenue = CEAISejour::storeSejour($newVenue, $sender);
                             $commentaire = CEAISejour::getComment($newVenue);
                             $_code_NumDos = "A121";
                             $_code_Venue = true;
                         }
                     }
                 } else {
                     $collision = $newVenue->getCollisions();
                     if (count($collision) == 1) {
                         $newVenue = reset($collision);
                         // Dans le cas d'une annulation de la venue
                         if ($cancel) {
                             if ($msgAcq = $this->doNotCancelVenue($newVenue, $dom_acq, $echg_hprim)) {
                                 return $msgAcq;
                             }
                         }
                         // Recherche d'un num dossier déjà existant pour cette venue
                         // Mise en trash du numéro de dossier reçu
                         $newVenue->loadNDA();
                         if ($this->trashNDA($newVenue, $sender)) {
                             $nda->_trash = true;
                         } else {
                             // Mapping du séjour
                             $newVenue = $this->mappingVenue($data['venue'], $newVenue, $cancel);
                             $msgVenue = CEAISejour::storeSejour($newVenue, $sender);
                             $commentaire = CEAISejour::getComment($newVenue);
                             $_code_NumDos = "A122";
                             $_code_Venue = true;
                         }
                     }
                 }
                 if (!$newVenue->_id && !isset($nda->_trash)) {
                     // Mapping du séjour
                     $newVenue = $this->mappingVenue($data['venue'], $newVenue, $cancel);
                     $msgVenue = CEAISejour::storeSejour($newVenue, $sender);
                     $commentaire = CEAISejour::getComment($newVenue);
                 }
             }
             if (isset($nda->_trash)) {
                 $nda->tag = CAppUI::conf('dPplanningOp CSejour tag_dossier_trash') . $sender->_tag_sejour;
                 $nda->loadMatchingObject();
                 $codes = array("I125");
                 $commentaire = "Sejour non récupéré. Impossible d'associer le numéro de dossier.";
             }
             if ($cancel) {
                 $codes[] = "A130";
                 $nda->tag = CAppUI::conf('dPplanningOp CSejour tag_dossier_trash') . $sender->_tag_sejour;
             }
             $msgNDA = CEAISejour::storeNDA($nda, $newVenue, $sender);
             if (!isset($nda->_trash)) {
                 $codes = array($msgVenue ? $_code_Venue ? "A103" : "A102" : ($_code_Venue ? "I102" : "I101"), $msgNDA ? "A105" : $_code_NumDos);
             }
             if ($msgVenue || $msgNDA) {
                 $avertissement = $msgVenue . " " . $msgNDA;
             } else {
                 if (!isset($nda->_trash)) {
                     $commentaire .= "Numéro dossier créé : {$nda->id400}.";
                 }
             }
         } else {
             $newVenue->_NDA = $nda->id400;
             $newVenue->load($nda->object_id);
             // Dans le cas d'une annulation de la venue
             if ($cancel) {
                 if ($msgAcq = $this->doNotCancelVenue($newVenue, $dom_acq, $echg_hprim)) {
                     return $msgAcq;
                 }
             }
             // Mapping du séjour
             $newVenue = $this->mappingVenue($data['venue'], $newVenue, $cancel);
             // idCible non fourni
             if (!$idCibleVenue) {
                 $_code_NumDos = "I123";
             } else {
                 $tmpVenue = new CSejour();
                 // idCible connu
                 if ($tmpVenue->load($idCibleVenue)) {
                     if ($tmpVenue->_id != $nda->object_id) {
                         $commentaire = "L'identifiant source fait référence au séjour : {$nda->object_id}";
                         $commentaire .= "et l'identifiant cible au séjour : {$tmpVenue->_id}.";
                         return $dom_acq->generateAcquittementsError("E104", $commentaire, $newVenue);
                     }
                     $_code_NumDos = "I124";
                 } else {
                     $_code_NumDos = "A120";
                 }
             }
             $msgVenue = CEAISejour::storeSejour($newVenue, $sender);
             $codes = array($msgVenue ? "A103" : "I102", $_code_NumDos);
             if ($cancel) {
                 $codes[] = "A130";
                 $nda->tag = CAppUI::conf('dPplanningOp CSejour tag_dossier_trash') . $sender->_tag_sejour;
                 $nda->last_update = CMbDT::dateTime();
                 $msgNDA = $nda->store();
             }
             if ($msgVenue || $msgNDA) {
                 $avertissement = $msgVenue . " " . $msgNDA;
             }
             $commentaire = CEAISejour::getComment($newVenue);
         }
         return $echg_hprim->setAck($dom_acq, $codes, $avertissement, $commentaire, $newVenue);
     }
 }
 /**
  * Handle event A45 - move visit information - visit number
  *
  * @param CHL7Acknowledgment $ack        Acknowledgment
  * @param CPatient           $newPatient Person
  * @param array              $data       Datas
  *
  * @return string
  */
 function handleA45(CHL7Acknowledgment $ack, CPatient $newPatient, $data)
 {
     $exchange_hl7v2 = $this->_ref_exchange_hl7v2;
     $sender = $exchange_hl7v2->_ref_sender;
     // On considère que l'on a qu'un changement à faire
     if (count($data["merge"]) > 1) {
         return $exchange_hl7v2->setAckAR($ack, "E701", null, $newPatient);
     }
     $merge = CValue::read($data["merge"], 0);
     $keep_patient = new CPatient();
     $patientPI = CValue::read($data['personIdentifiers'], "PI");
     // Acquittement d'erreur : identifiants RI et PI non fournis
     if (!$patientPI) {
         return $exchange_hl7v2->setAckAR($ack, "E100", null, $newPatient);
     }
     // Chargement du patient
     $idexPatient = CIdSante400::getMatch("CPatient", $sender->_tag_patient, $patientPI);
     $keep_patient->load($idexPatient->object_id);
     if (!$keep_patient->_id) {
         return $exchange_hl7v2->setAckAR($ack, "E702", null, $keep_patient);
     }
     // MRG-1 Ancien numéro du patient
     // Chargement du séjour pour ce patient
     $MRG_1 = $this->queryTextNode("MRG.1/CX.1", $merge["MRG"]);
     $idex = new CIdSante400();
     $idex->object_class = "CPatient";
     $idex->id400 = $MRG_1;
     $idex->tag = $sender->_tag_patient;
     /** @var CPatient $patient_removing */
     $patient_removing = $idex->getMbObject();
     if (!$patient_removing || !$patient_removing->_id) {
         return $exchange_hl7v2->setAckAR($ack, "E703", null, $newPatient);
     }
     // MRG-5 Numéro de dossier
     // Chargement du dossier par le numéro de séjour
     $MRG_5 = $this->queryTextNode("MRG.5/CX.1", $merge["MRG"]);
     $idex = new CIdSante400();
     $idex->object_class = "CSejour";
     $idex->id400 = $MRG_5;
     $idex->tag = $sender->_tag_sejour;
     /** @var CSejour $venue */
     $venue = $idex->getMbObject();
     if (!$venue || !$venue->_id) {
         return $exchange_hl7v2->setAckAR($ack, "E704", null, $newPatient);
     }
     // Si le patient du séjour retrouvé est différent de celui que l'on doit "supprimer"
     if ($venue->patient_id != $patient_removing->_id) {
         return $exchange_hl7v2->setAckAR($ack, "E705", null, $venue);
     }
     // Réattribution du patient_id sur le séjour
     // Impossibilité dans Mediboard de modifier le patient d'un séjour ayant une entrée réelle
     if (CAppUI::conf("dPplanningOp CSejour patient_id") == 2 && $venue->entree_reelle) {
         return $exchange_hl7v2->setAckAR($ack, "E706", null, $venue);
     }
     $venue->patient_id = $keep_patient->_id;
     // Notifier les autres destinataires autre que le sender
     $venue->_eai_sender_guid = $sender->_guid;
     if ($msg = $venue->store()) {
         return $exchange_hl7v2->setAckAR($ack, "E707", $msg, $venue);
     }
     $comment = CEAISejour::getComment($venue);
     return $exchange_hl7v2->setAckAA($ack, "I700", $comment, $venue);
 }
 /**
  * Fusion and recording a stay with an num_dos in the system
  *
  * @param CHPrimXMLAcquittementsPatients $dom_acq    Acquittement
  * @param CPatient                       $newPatient Patient
  * @param array                          $data       Data
  *
  * @return string acquittement 
  **/
 function mouvementPatient(CHPrimXMLAcquittementsPatients $dom_acq, CPatient $newPatient, $data)
 {
     $echg_hprim = $this->_ref_echange_hprim;
     $sender = $echg_hprim->_ref_sender;
     $sender->loadConfigValues();
     $this->_ref_sender = $sender;
     // Traitement de la venue
     $newVenue = new CSejour();
     $domVenuePatient = new CHPrimXMLVenuePatient();
     $domVenuePatient->_ref_echange_hprim = $echg_hprim;
     $msgAcq = $domVenuePatient->venuePatient($dom_acq, $newPatient, $data, $newVenue);
     if ($echg_hprim->statut_acquittement != "OK") {
         return $msgAcq;
     }
     $dom_acq = new CHPrimXMLAcquittementsPatients();
     $dom_acq->_identifiant_acquitte = $data['identifiantMessage'];
     $dom_acq->_sous_type_evt = $this->sous_type;
     $dom_acq->_ref_echange_hprim = $echg_hprim;
     // Mapping venue - création impossible
     if (!$this->admitFound($newVenue, $data)) {
         return $echg_hprim->setAckError($dom_acq, "E014", null, $newVenue);
     }
     $codes = array();
     $avertissement = $comment = null;
     if (!CAppUI::conf("hprimxml mvtComplet") || CAppUI::conf('smp server')) {
         return $echg_hprim->setAck($dom_acq, $codes, $avertissement, $comment, $newVenue);
     }
     // Mapping des mouvements
     $msgMovement = $this->mappingMouvements($data['mouvements'], $newVenue);
     // Notifier les autres destinataires
     $newVenue->_eai_sender_guid = $sender->_guid;
     $newVenue->store();
     $codes = array($msgMovement ? "A301" : "I301");
     if ($msgMovement) {
         $avertissement = $msgMovement . " ";
     }
     $comment = CEAISejour::getComment($newVenue);
     return $echg_hprim->setAck($dom_acq, $codes, $avertissement, $comment, $newVenue);
 }
 /**
  * Mapping et enregistrement de la venue
  *
  * @param CSejour     &$newVenue          Séjour
  * @param array       $data               Datas
  * @param string      $etatVenueEliminee  État de la venue à éliminer
  * @param CIdSante400 &$idexVenue         Idex de la venue
  * @param CIdSante400 &$idexVenueEliminee Idex de la venue à éliminer
  *
  * @return array
  */
 private function mapAndStoreVenue(&$newVenue, $data, $etatVenueEliminee, CIdSante400 &$idexVenue, CIdSante400 &$idexVenueEliminee)
 {
     $sender = new CDestinataireHprim();
     $sender->nom = $data['idClient'];
     $sender->loadMatchingObject();
     $messages = array();
     // Mapping de la venue a éliminer
     $newVenue = $this->mappingVenue($data['venueEliminee'], $newVenue);
     // Mapping de la venue a garder
     $newVenue = $this->mappingVenue($data['venue'], $newVenue);
     // Notifier les autres destinataires
     $newVenue->_eai_sender_guid = $sender->_guid;
     // Séjour retrouvé
     if ($newVenue->loadMatchingSejour() || $newVenue->_id) {
         $messages['_code_NumDos'] = "A121";
         $messages['_code_Venue'] = "store";
     } else {
         $messages['_code_NumDos'] = "I122";
         $messages['_code_Venue'] = "create";
     }
     $messages['msgVenue'] = $newVenue->store();
     $messages['commentaire'] = CEAISejour::getComment($newVenue);
     $idexVenue->object_id = $newVenue->_id;
     $idexVenue->last_update = CMbDT::dateTime();
     $messages['msgNumDosVenue'] = $idexVenue->store();
     $idexVenueEliminee->tag = $etatVenueEliminee != "préadmission" ? CAppUI::conf('dPplanningOp CSejour tag_dossier_cancel') . $sender->_tag_sejour : CAppUI::conf('dPplanningOp CSejour tag_dossier_pa') . $sender->_tag_sejour;
     $idexVenueEliminee->object_id = $newVenue->_id;
     $idexVenueEliminee->last_update = CMbDT::dateTime();
     $messages['msgNumDosVenueEliminee'] = $idexVenueEliminee->store();
     return $messages;
 }