protected function _sendBulkEvent($txId, $errors)
 {
     $event = new EventModel();
     $event->entityId = $txId;
     $event->entityType = 'transaction';
     $event->namespace = 'connectivity';
     $event->created = time();
     $event->modified = time();
     $event->pushEventData = true;
     $eventData = array();
     if (!empty($errors)) {
         $eventData['hasFailures'] = true;
         $eventData['message'] = array('failed' => $errors);
     } else {
         $eventData['hasFailures'] = false;
     }
     $event->eventData = $eventData;
     $event->forceFinish = true;
     $compressor = new ErrorModelCompressEvent();
     $compressor->compress($event);
     WatcherService::getInstance()->publishEvent($event);
 }
 /**
  *
  * @param string $filename
  */
 public function uploadBulk($filename)
 {
     // Open file
     if (!stat($filename)) {
         throw new \Application\Exceptions\UnexpectedException("Error opening file {$filename}");
     }
     $fd = fopen($filename, 'r');
     $sep = \App_Parser_CsvParser::getCsvSeparator($fd);
     // Request
     $sims = array();
     $validator = new SimBulkValidate();
     $validHeaders = $this->getUploadBulkHeaders();
     $filter = \Zend_Controller_Action_HelperBroker::getStaticHelper('FilterNotAllowedFields');
     // CSV
     $header = fgetcsv($fd, 0, $sep);
     // Header
     $prows = 0;
     // Packet rows
     $irows = 1;
     // Iteration rows
     $nrows = 1;
     // Total rows
     $ncols = count($header);
     // Total columns
     $validH = false;
     foreach ($header as $h) {
         if (isset($validHeaders[$h])) {
             $validH = true;
             break;
         }
     }
     // Check lines readed
     if (!$validH) {
         \App::log()->debug("[UpdateBulk] No valid headers");
         throw new ValidateException("No valid headers", ValidationCodes::FILE_NO_VALID_HEADERS);
     }
     if (in_array('locationManual_latitude', $header) && !in_array('locationManual_longitude', $header) || in_array('locationManual_longitude', $header) && !in_array('locationManual_latitude', $header)) {
         \App::log()->debug("[UpdateBulk] No valid headers: location requires latitude and longitude");
         throw new ValidateException("No valid headers: location requires latitude and longitude", ValidationCodes::FILE_NO_VALID_HEADERS_LOCATION);
     }
     $bulkCount = \App::config('ericssonserviceCallItemCount', self::BULK_UPDATE_DEFAULT);
     // I'm not sure... I don't like it.
     set_time_limit(0);
     $watcher = $this->getMapper()->createFileWatcher();
     $txId = uniqid("bulk");
     $watcher->entityIds = array($txId);
     $watcher->params->action = "bulkSimUpdate";
     WatcherService::getInstance()->create($watcher);
     $errors = array();
     $warnings = array();
     $ntxs = 0;
     // Rows
     while (($line = fgetcsv($fd, 0, $sep)) !== false) {
         // Next line has been readed
         $nrows++;
         // Check columns
         if (count($line) !== $ncols) {
             $errors[] = new Model\ErrorModel(array('line' => $nrows, 'description' => "Incorrect format (number of columns)", 'level' => Model\ErrorModel::ERROR_LEVEL_ERROR, 'code' => ValidationCodes::FILE_READING_ERR));
             continue;
         }
         // Create sim
         $data = array();
         foreach ($header as $key => $name) {
             // \App::log()->debug("[UpdateBulk] $name : $key");
             if (!isset($validHeaders[$name])) {
                 // Ignore invalid columns
                 //                     \App::log()->warn("[UpdateBulk] Ignoring $name column");
                 continue;
             }
             $value = $line[$key];
             if (preg_match('/^=\\"(?P<value>.*)\\"$/', $value, $matches)) {
                 $value = $matches['value'];
             }
             // GLOBALPORTAL-28668
             // if (!empty($value)) {
             // \App::log()->debug("[UpdateBulk] $name : $value");
             if (isset($value) && (!empty($value) || is_numeric($value))) {
                 // \App::log()->debug("[UpdateBulk] TRUE $name : $value");
                 // Remove field?
                 // See SimBaseMapper _mapModelToEricssonModel method,
                 // SimValidate and App_Validate_ReferenceIndex to understand it
                 if ($value === '-' && $name !== 'staticIpApnIndex') {
                     $value = '';
                 }
                 // Process field
                 if (strpos($name, 'apn_') !== false) {
                     // In order to remove the current value of a SIM´s field,
                     // the character - must be indicated
                     $index = (int) substr($name, strlen('apn_apn')) - 1;
                     $data['apns'][$index] = $value;
                 } else {
                     if (strpos($name, 'locationManual_') !== false) {
                         $value = str_replace(',', '.', $value);
                         if (!is_numeric($value)) {
                             $warnings[] = new Model\ErrorModel(array('line' => $nrows, 'column' => $name, 'description' => "Invalid value", 'level' => Model\ErrorModel::ERROR_LEVEL_WARN, 'code' => ValidationCodes::INVALID_VALUE));
                         } else {
                             $subname = substr($name, strlen('locationManual_'));
                             $value = floatval(str_replace(',', '.', $value));
                             $data['locationManual'][$subname] = (int) round($value * pow(10, 6));
                         }
                     } else {
                         if ($name == 'LTE_status') {
                             if ($value != SimModel::LTE_ACTIVE && $value != SimModel::LTE_INACTIVE) {
                                 $warnings[] = new Model\ErrorModel(array('line' => $nrows, 'column' => $name, 'description' => "Invalid value", 'level' => Model\ErrorModel::ERROR_LEVEL_WARN, 'code' => ValidationCodes::INVALID_VALUE));
                             } else {
                                 $data['lteEnabled'] = $value == SimModel::LTE_ACTIVE ? true : false;
                             }
                         } else {
                             $data[$name] = $value;
                         }
                     }
                 }
             }
         }
         // Create and validate sim
         $sim = new SimModel($data);
         $v = $this->validate($sim, false, $validator);
         if ($v === true) {
             // Backup id
             $ids = $sim->getIds();
             $type = key($ids);
             $value = current($ids);
             //Inject organization
             $org = \App::getOrgUserLogged();
             switch ($org->getType()) {
                 case OrgMasterModel::ORG_TYPE:
                     $sim->setMaster($org);
                     break;
                 case OrgServiceProviderModel::ORG_TYPE:
                     $sim->setServiceProviderCommercial($org);
                     $sim->setServiceProviderEnabler($org);
                     break;
                 case OrgCustomerModel::ORG_TYPE:
                     $sim->setCustomer($org);
                     break;
                 case OrgAggregatorModel::ORG_TYPE:
                     $sim->setAggregator($org);
                     break;
                 case OrgEndUserModel::ORG_TYPE:
                     $sim->setEndUser($org);
                     break;
             }
             // Filter by permissions
             $filter->direct('update_field', $sim);
             // Recover id and add sim to request
             $sim->{$type} = $value;
             $sims[] = $sim;
             $prows++;
         } else {
             \App::log()->warn("[UpdateBulk] Ignoring invalid sim: " . json_encode($v));
             // Sending first validation error ONLY?
             foreach ($validator->getValidationCodes() as $field => $code) {
                 $errors[] = new Model\ErrorModel(array('line' => $nrows, 'description' => $field, 'level' => Model\ErrorModel::ERROR_LEVEL_WARN, 'code' => $code ?: ValidationCodes::MODEL_SIM));
             }
         }
         // Wait until packet is full
         if ($prows == $bulkCount) {
             // Send to Ericsson
             $this->_uploadBulk($sims, $errors, $irows, $nrows, $watcher);
             $ntxs++;
             // Reset packet list
             $sims = array();
             $prows = 0;
             // Update CSV line position
             $irows = $nrows + 1;
         }
     }
     // Ensure all sims have been sent (last packet)
     if (!empty($sims)) {
         // Send to Ericsson
         $this->_uploadBulk($sims, $errors, $irows, $nrows, $watcher);
         $ntxs++;
         // Reset packet list (memory propouses)
         $sims = array();
     }
     // Check lines readed
     if ($nrows < 2) {
         \App::log()->debug("[UpdateBulk] Ignoring empty file");
         $watcher->delete();
         throw new ValidateException("Missing file rows");
     }
     $event = $this->getMapper()->constructEventToTransaction();
     $event->entityId = $txId;
     // Add error code suffix
     if (isset($errors) && is_array($errors)) {
         foreach ($errors as $errMess) {
             require_once APPLICATION_PATH . '/modules/default/controllers/ErrorController.php';
             $errMess->code = \ErrorController::finishErrorCode($errMess->code);
         }
     }
     $eventData = array('simParsed' => $nrows - 1);
     if (!empty($errors) || !empty($warnings)) {
         $eventData['hasFailures'] = true;
         if (!empty($errors)) {
             $eventData['message']['failed'] = $errors;
         }
         if (!empty($warnings)) {
             $eventData['message']['warnings'] = $warnings;
         }
     } else {
         $eventData['hasFailures'] = false;
     }
     $event->eventData = $eventData;
     $compressor = new ErrorModelCompressEvent();
     $compressor->compress($event);
     WatcherService::getInstance()->publishEvent($event);
     $nerr = count($errors);
     \App::audit("Bulk update ({$nrows} sims in {$ntxs} requests with {$nerr} errors)", null);
     return $watcher->reload();
 }
 protected function _sendEvent($txId, $res, $parseResult)
 {
     if (!empty($res) && is_array($res)) {
         require_once APPLICATION_PATH . '/modules/default/controllers/ErrorController.php';
         foreach ($res as $errMess) {
             $errMess->code = \ErrorController::finishErrorCode($errMess->code);
         }
     }
     $event = StockMapper::getInstance()->constructEventToTransaction();
     $event->entityId = $txId;
     $eventData = array('simParsed' => isset($parseResult['count']) ? $parseResult['count'] : 0);
     if (!empty($res)) {
         $eventData['hasFailures'] = true;
         $eventData['message'] = array('failed' => $res);
     } else {
         $eventData['hasFailures'] = false;
     }
     $event->eventData = $eventData;
     $compressor = new ErrorModelCompressEvent();
     $compressor->compress($event);
     WatcherService::getInstance()->publishEvent($event);
 }
 protected function _loadErrorsFromWatcher($watcher)
 {
     $watcher->reloadUntilFinish();
     $failed = array();
     $compressedFailed = array();
     foreach ($watcher->eventList as $event) {
         if (@$event->eventData['hasFailures']) {
             if (isset($event->eventData['message']['failed'])) {
                 $failed = array_merge($failed, $event->eventData['message']['failed']);
             } else {
                 if (isset($event->eventData['message']['compressedFailed'])) {
                     foreach ($event->eventData['message']['compressedFailed'] as $key => $err) {
                         $this->_mergeCompressedErrors($compressedFailed, $key, $err);
                     }
                 }
             }
         }
     }
     if (count($compressedFailed)) {
         if (count($failed)) {
             $event = new EventModel();
             $eventData['hasFailures'] = true;
             $eventData['message'] = array('failed' => $failed);
             $event->eventData = $eventData;
             $compressor = new ErrorModelCompressEvent();
             $compressor->setConfigMaxErrorsBeforeCompress(0);
             $compressor->compress($event);
             if (isset($event->eventData['message']['compressedFailed'])) {
                 foreach ($event->eventData['compressedFailed'] as $key => $err) {
                     $this->_mergeCompressedErrors($compressedFailed, $key, $err);
                 }
             }
         }
         return $compressedFailed;
     }
     return $failed;
 }