/** * General function to receive * * @return array list of files received */ public function receive() { foreach (Billrun_Factory::config()->getConfigValue('ilds.providers', array()) as $type) { if (!file_exists($this->workspace . DIRECTORY_SEPARATOR . $type)) { Billrun_Factory::log()->log("NOTICE : SKIPPING {$type} !!! directory " . $this->workspace . DIRECTORY_SEPARATOR . $type . " not found!!", Zend_Log::NOTICE); continue; } $files = scandir($this->workspace . DIRECTORY_SEPARATOR . $type); $ret = array(); static::$type = $type; foreach ($files as $file) { $path = $this->workspace . DIRECTORY_SEPARATOR . $type . DIRECTORY_SEPARATOR . $file; if (is_dir($path) || $this->lockFileForReceive($file, $type) || !$this->isFileValid($file, $path)) { continue; } $fileData = $this->getFileLogData($file, $type); $fileData['path'] = $path; if (!empty($this->backupPaths)) { $backedTo = $this->backup($fileData['path'], $file, $this->backupPaths, FALSE, FALSE); Billrun_Factory::dispatcher()->trigger('beforeReceiverBackup', array($this, &$fileData['path'])); $fileData['backed_to'] = $backedTo; Billrun_Factory::dispatcher()->trigger('afterReceiverBackup', array($this, &$fileData['path'])); } $this->logDB($fileData); $ret[] = $fileData['path']; } $this->processType($type); } return $ret; }
/** * load the container the need to be generate */ public function load() { $billrun = Billrun_Factory::db()->billrunCollection(); $this->data = $billrun->query()->equals('stamp', $this->getStamp())->equals('source', 'ilds')->notExists('invoice_id'); Billrun_Factory::log()->log("aggregator entities loaded: " . $this->data->count(), Zend_Log::INFO); Billrun_Factory::dispatcher()->trigger('afterGeneratorLoadData', array('generator' => $this)); }
/** * load the container the need to be generate */ public function load() { $this->data = $this->collection->aggregate($this->aggregation_array); //TODO how to perform it on the secondaries? Billrun_Factory::log()->log("generator entities loaded: " . count($this->data), Zend_Log::INFO); Billrun_Factory::dispatcher()->trigger('afterGeneratorLoadData', array('generator' => $this)); }
public function updateRow($row) { Billrun_Factory::dispatcher()->trigger('beforeCalculatorWriteRow', array($row, $this)); $carrierOut = $this->detectCarrierOut($row); $carrierIn = $this->detectCarrierIn($row); $current = $row->getRawData(); $added_values = array($this->ratingField => $carrierOut ? $carrierOut->createRef(Billrun_Factory::db()->carriersCollection()) : $carrierOut, $this->ratingField . '_in' => $carrierIn ? $carrierIn->createRef(Billrun_Factory::db()->carriersCollection()) : $carrierIn); $newData = array_merge($current, $added_values); $row->setRawData($newData); Billrun_Factory::dispatcher()->trigger('afterCalculatorWriteRow', array($row, $this)); return true; }
/** * write the calculation into DB. * @param $row the line CDR to update. */ public function updateRow($row) { Billrun_Factory::dispatcher()->trigger('beforeCalculatorWriteRow', array($row, $this)); $current = $row->getRawData(); $usage_type = $this->getLineUsageType($row); $volume = $this->getLineVolume($row, $usage_type); $rate = $this->getLineRate($row, $usage_type); $added_values = array('usaget' => $usage_type, 'usagev' => $volume, $this->ratingField => $rate ? $rate->createRef() : $rate); $newData = array_merge($current, $added_values); $row->setRawData($newData); Billrun_Factory::dispatcher()->trigger('afterCalculatorWriteRow', array($row, $this)); return true; }
/** * Write the calculation into DB */ public function updateRow($row) { Billrun_Factory::dispatcher()->trigger('beforeCalculatorUpdateRow', array($row, $this)); //Billrun_Factory::log()->log("Line start : getLineZone start : ".microtime(true)); $rate = $this->getLineZone($row, $row['usaget']); //Billrun_Factory::log()->log(" getLineZone end : ".microtime(true)); $current = $row->getRawData(); $added_values = array($this->ratingField => $rate instanceof Mongodloid_Entity ? $rate->createRef() : $rate); $newData = array_merge($current, $added_values); $row->setRawData($newData); Billrun_Factory::dispatcher()->trigger('afterCalculatorUpdateRow', array($row, $this)); return $row; }
/** * load the data to aggregate */ public function load() { $billrun_key = $this->getStamp(); $subscriber = Billrun_Factory::subscriber(); $filename = $billrun_key . '_leftover_aggregator_input'; Billrun_Factory::log()->log("Loading file " . $filename, Zend_Log::INFO); $billrun_end_time = Billrun_Util::getEndTime($billrun_key); $this->data = $subscriber->getListFromFile('files/' . $filename, $billrun_end_time); if (!count($this->data)) { Billrun_Factory::log()->log("No accounts were found for leftover aggregator", Zend_Log::ALERT); } if (is_array($this->data)) { $this->data = array_slice($this->data, $this->page * $this->size, $this->size, TRUE); } Billrun_Factory::log()->log("aggregator entities loaded: " . count($this->data), Zend_Log::INFO); Billrun_Factory::dispatcher()->trigger('afterAggregatorLoadData', array('aggregator' => $this)); }
/** * method to log the processing * * @todo refactoring this method */ protected function logDB($fileData) { $log = Billrun_Factory::db()->logCollection(); Billrun_Factory::dispatcher()->trigger('beforeLogReceiveFile', array(&$fileData, $this)); $query = array('stamp' => $fileData['stamp'], 'received_time' => array('$exists' => false)); $addData = array('received_hostname' => Billrun_Util::getHostName(), 'received_time' => date(self::base_dateformat)); $update = array('$set' => array_merge($fileData, $addData)); if (empty($query['stamp'])) { Billrun_Factory::log()->log("Billrun_Receiver::logDB - got file with empty stamp : {$fileData['stamp']}", Zend_Log::NOTICE); return FALSE; } $result = $log->update($query, $update, array('w' => 1)); if ($result['ok'] != 1 || $result['n'] != 1) { Billrun_Factory::log()->log("Billrun_Receiver::logDB - Failed when trying to update a file log record " . $fileData['file_name'] . " with stamp of : {$fileData['stamp']}", Zend_Log::NOTICE); } return $result['n'] == 1 && $result['ok'] == 1; }
/** * general function to receive * * @return mixed */ public function respond() { Billrun_Factory::dispatcher()->trigger('beforeResponse', array('type' => self::$type, 'responder' => &$this)); $retPaths = array(); foreach ($this->getProcessedFilesForType(self::$type) as $filename => $logLine) { $filePath = $this->workspace . DIRECTORY_SEPARATOR . self::$type . DIRECTORY_SEPARATOR . $filename; if (!file_exists($filePath)) { Billrun_Factory::log()->log("NOTICE : SKIPPING {$filename} for type : " . self::$type . "!!! ,path - {$filePath} not found!!", Zend_Log::NOTICE); continue; } $responseFilePath = $this->processFileForResponse($filePath, $logLine, $filename); if ($responseFilePath) { $retPaths[] = $this->respondAFile($responseFilePath, $this->getResponseFilename($filename, $logLine), $logLine); } } Billrun_Factory::dispatcher()->trigger('afterResponse', array('type' => self::$type, 'responder' => &$this)); return $retPaths; }
/** * Move the file to the workspace. * * @param string $srcPath The original file position * @param string $filename the filename * * @return mixed the new path if success, else false */ protected function handleFile($srcPath, $filename) { Billrun_Factory::log('Relocate receive handle file ' . $filename, Zend_Log::INFO); $srcPath = parent::handleFile($srcPath, $filename); Billrun_Factory::dispatcher()->trigger('beforeRelocateFileHandling', array($this, &$srcPath, $filename)); $newPath = $this->workspace . DIRECTORY_SEPARATOR . static::$type; if (!file_exists($newPath)) { mkdir($newPath, 0777, true); } $newPath .= DIRECTORY_SEPARATOR . $filename; $ret = $this->moveFiles ? copy($srcPath, $newPath) && unlink($srcPath) : copy($srcPath, $newPath); if ($this->preserve_timestamps) { $timestamp = filemtime($srcPath); Billrun_Util::setFileModificationTime($newPath, $timestamp); } Billrun_Factory::dispatcher()->trigger('afterRelocateFileHandling', array($this, &$srcPath, &$newPath, $filename, $ret)); return $ret ? $newPath : FALSE; }
/** * method to parse data * * @param array $line data line * * @return array the data array */ protected function parseData($line) { if (!isset($this->data['header'])) { Billrun_Factory::log()->log("No header found", Zend_Log::ERR); return false; } $data_type = strtolower($this->getLineType($line, $this->parser->getSeparator())); // can be moc or mtc $this->parser->setStructure($this->{$data_type . "_structure"}); // for the next iteration $this->parser->setLine($line); Billrun_Factory::dispatcher()->trigger('beforeDataParsing', array(&$line, $this)); $row = $this->parser->parse(); $row['source'] = static::$type; $row['log_stamp'] = $this->getFileStamp(); $row['file'] = basename($this->filePath); $row['process_time'] = date(self::base_dateformat); Billrun_Factory::dispatcher()->trigger('afterDataParsing', array(&$row, $this)); $this->data['data'][] = $row; return $row; }
/** * make the calculation */ public function updateRow($row) { Billrun_Factory::dispatcher()->trigger('beforeCalculatorUpdateRow', array($row, $this)); $pricingData = array(); $row->collection(Billrun_Factory::db()->linesCollection()); $zoneKey = $this->isLineIncoming($row) ? 'incoming' : $this->loadDBRef($row->get(Billrun_Calculator_Wholesale_Nsn::MAIN_DB_FIELD, true))['key']; if (isset($row['usagev']) && $zoneKey) { $rates = $this->getCarrierRateForZoneAndType($this->loadDBRef($row->get($this->isLineIncoming($row) ? 'wsc_in' : 'wsc', true)), $zoneKey, $row['usaget'], $this->isPeak($row) ? 'peak' : 'off_peak'); if ($rates) { $pricingData = $this->getLinePricingData($row['usagev'], $rates); //todo add peak/off peak to the data. $row->setRawData(array_merge($row->getRawData(), $pricingData)); } else { Billrun_Factory::log()->log(" Failed finding rate for row : " . print_r($row['stamp'], 1), Zend_Log::DEBUG); } } else { Billrun_Factory::log()->log($this->count++ . " no usagev or zone : {$row['usagev']} && {$zoneKey} for line with stamp: " . $row['stamp'], Zend_Log::NOTICE); return false; } Billrun_Factory::dispatcher()->trigger('afterCalculatorUpdateRow', array($row, $this)); return $row; }
public function updateRow($row) { Billrun_Factory::dispatcher()->trigger('beforeCalculatorUpdateRow', array($row, $this)); //@TODO change this be be configurable. $pricingData = array(); $row->collection(Billrun_Factory::db()->linesCollection()); $zoneKey = $this->isLineIncoming($row) ? 'incoming' : $this->loadDBRef($row->get(Billrun_Calculator_Wholesale_Nsn::MAIN_DB_FIELD, true))['key']; if (isset($row['usagev']) && $zoneKey) { $carir = $this->loadDBRef($row->get(in_array($row->get('wsc', true), $this->nrCarriers) ? 'wsc' : 'wsc_in', true)); $rates = $this->getCarrierRateForZoneAndType($carir, $zoneKey, $row['usaget']); if (!$rates) { Billrun_Factory::log()->log(" Failed finding rate for row : " . print_r($row['stamp'], 1), Zend_Log::DEBUG); return false; } $pricingData = $this->getLinePricingData($row['usagev'], $rates); $row->setRawData(array_merge($row->getRawData(), $pricingData)); } else { Billrun_Factory::log()->log(" No usagev or zone : {$row['usagev']} && {$zoneKey} for line with stamp: " . $row['stamp'], Zend_Log::NOTICE); return false; } Billrun_Factory::dispatcher()->trigger('afterCalculatorUpdateRow', array($row, $this)); return $row; }
public function process() { if ($this->isQueueFull()) { Billrun_Factory::log()->log("Billrun_Processor_Base_BlockedSeperatedBinary: queue size is too big", Zend_Log::INFO); return FALSE; } else { // run all over the file with the parser helper if (!is_resource($this->fileHandler)) { Billrun_Factory::log()->log("Resource is not configured well", Zend_Log::ERR); return false; } $this->data['trailer'] = array(); $this->data['header'] = $this->buildHeader(false); Billrun_Factory::dispatcher()->trigger('beforeProcessorParsing', array($this)); while (!$this->processFinished()) { if ($this->parse() === FALSE) { Billrun_Factory::log()->log("Billrun_Processor: cannot parse", Zend_Log::ERR); return false; } } $this->data['trailer'] = $this->buildTrailer($this->data['trailer']); Billrun_Factory::dispatcher()->trigger('afterProcessorParsing', array($this)); $this->prepareQueue(); Billrun_Factory::dispatcher()->trigger('beforeProcessorStore', array($this)); if ($this->store() === FALSE) { Billrun_Factory::log()->log("Billrun_Processor: cannot store the parser lines", Zend_Log::ERR); return false; } if ($this->logDB() === FALSE) { Billrun_Factory::log()->log("Billrun_Processor: cannot log parsing action", Zend_Log::WARN); } Billrun_Factory::dispatcher()->trigger('afterProcessorStore', array($this)); $this->backup(); Billrun_Factory::dispatcher()->trigger('afterProcessorBackup', array($this, &$this->filePath)); return count($this->data['data']); } }
/** * method to parse footer * * @param array $line footer line * * @return array the footer array */ protected function parseFooter($line) { if (isset($this->data['trailer'])) { Billrun_Factory::log()->log("double trailer", Zend_Log::ERR); return false; } $this->parser->setStructure($this->trailer_structure); $this->parser->setLine($line); Billrun_Factory::dispatcher()->trigger('beforeFooterParsing', array($line, $this)); $trailer = $this->parser->parse(); $trailer['source'] = static::$type; $trailer['type'] = self::$type; $trailer['header_stamp'] = $this->data['header']['stamp']; $trailer['file'] = basename($this->filePath); $trailer['process_time'] = date(self::base_dateformat); Billrun_Factory::dispatcher()->trigger('afterFooterParsing', array($trailer, $this)); $this->data['trailer'] = $trailer; return $trailer; }
protected function handleFile() { $ret = FALSE; Billrun_Factory::dispatcher()->trigger('beforeInlineFileHandling', array($this)); $newPath = $this->getDestBasePath(); @mkdir($newPath, 0755, true); if (file_exists($newPath)) { $newPath .= DIRECTORY_SEPARATOR . $this->filename; $ret = file_put_contents($newPath, $this->file_content); Billrun_Factory::dispatcher()->trigger('afterInlineFileHandling', array($this, &$newPath, $ret)); } return $ret === FALSE ? FALSE : $newPath; }
/** * Move the file to the workspace. * * * @return string the new path */ protected function handleFile($srcPath, $filename) { Billrun_Factory::dispatcher()->trigger('handlingLocalFilesReceive', array($this, &$srcPath, $filename)); return $srcPath; }
/** * method to retrieve the dispatcher instance * * @return Billrun_Dispatcher */ public static function dispatcher() { if (!self::$dispatcher) { self::$dispatcher = Billrun_Dispatcher::getInstance(); } return self::$dispatcher; }
/** * Write the calculation into DB */ public function updateRow($row) { Billrun_Factory::dispatcher()->trigger('beforeCalculatorUpdateRow', array($row, $this)); $current = $row->getRawData(); $charge = $this->calcChargeLine($row->get('type'), $row->get('call_charge')); $added_values = array('aprice' => $charge, 'pprice' => $charge); $newData = array_merge($current, $added_values); $row->setRawData($newData); Billrun_Factory::dispatcher()->trigger('afterCalculatorUpdateRow', array($row, $this)); return $row; }
/** * load file to be handle by the processor * * @param string $file_path * * @return void */ public function loadFile($file_path, $retrivedHost = '') { Billrun_Factory::dispatcher()->trigger('processorBeforeFileLoad', array(&$file_path, $this)); if (file_exists($file_path)) { $this->filePath = $file_path; $this->filename = substr($file_path, strrpos($file_path, '/')); $this->retrievedHostname = $retrivedHost; $this->fileHandler = fopen($file_path, 'r'); Billrun_Factory::log()->log("Billrun Processor load the file: " . $file_path, Zend_Log::INFO); } else { Billrun_Factory::log()->log("Billrun_Processor->loadFile: cannot load the file: " . $file_path, Zend_Log::ERR); } Billrun_Factory::dispatcher()->trigger('processorAfterFileLoad', array(&$file_path)); }
/** * load the data to aggregate */ public function load() { $lines = Billrun_Factory::db()->linesCollection(); $this->data = $lines->query()->equals('source', 'ilds')->notExists('billrun')->exists('pprice')->exists('aprice')->cursor()->hint(array('source' => 1)); Billrun_Factory::log()->log("aggregator entities loaded: " . $this->data->count(), Zend_Log::INFO); Billrun_Factory::dispatcher()->trigger('afterAggregatorLoadData', array('aggregator' => $this)); }
/** * Save a modified line to the lines collection. * @param Mongodloid_Entity $line the line to write * @param mixed $dataKey the line key in the calculator's data container */ public function writeLine($line, $dataKey) { Billrun_Factory::dispatcher()->trigger('beforeCalculatorWriteLine', array('data' => $line)); $line->save(Billrun_Factory::db()->linesCollection()); Billrun_Factory::dispatcher()->trigger('afterCalculatorWriteLine', array('data' => $line)); if (!isset($line['usagev']) || $line['usagev'] === 0) { $this->removeLineFromQueue($line); unset($this->data[$dataKey]); } }
/** * make the calculation */ public function updateRow($row) { Billrun_Factory::dispatcher()->trigger('beforeCalculatorUpdateRow', array($row, $this)); $current = $row->getRawData(); $usage_type = $this->getLineUsageType($row); $volume = $this->getLineVolume($row, $usage_type); $rate = $this->getLineRate($row, $usage_type); if (isset($rate['key']) && $rate['key'] == "UNRATED") { return false; } $added_values = array('usaget' => $usage_type, 'usagev' => $volume, $this->ratingField => $rate ? $rate->createRef() : $rate); if ($rate) { $added_values[$this->aprField] = Billrun_Calculator_CustomerPricing::getPriceByRate($rate, $usage_type, $volume); } $newData = array_merge($current, $added_values); $row->setRawData($newData); Billrun_Factory::dispatcher()->trigger('afterCalculatorUpdateRow', array($row, $this)); return $row; }
/** * method to check if the file already processed */ protected function isFileReceived($filename, $type, $more_fields = array()) { $log = Billrun_Factory::db()->logCollection(); $query = array('source' => $type, 'file_name' => $filename); if (!empty($more_fields)) { $query = array_merge($query, $more_fields); } Billrun_Factory::dispatcher()->trigger('alertisFileReceivedQuery', array(&$query, $type, $this)); $resource = $log->query($query)->cursor()->limit(1); return $resource->count() > 0; }
/** * Override parent calculator to save changes with update (not save) */ public function writeLine($line, $dataKey) { Billrun_Factory::dispatcher()->trigger('beforeCalculatorWriteLine', array('data' => $line)); $save = array(); $saveProperties = array_keys(Billrun_Factory::subscriber()->getAvailableFields()); foreach ($saveProperties as $p) { if (!is_null($val = $line->get($p, true))) { $save['$set'][$p] = $val; } } $where = array('stamp' => $line['stamp']); Billrun_Factory::db()->linesCollection()->update($where, $save); Billrun_Factory::dispatcher()->trigger('afterCalculatorWriteLine', array('data' => $line)); if (!isset($line['usagev']) || $line['usagev'] === 0) { $this->removeLineFromQueue($line); unset($this->data[$dataKey]); } }
/** * method to receive the usage left in group of rates of current plan * * @param array $subscriberBalance subscriber balance * @param array $rate the rate to check the balance * @param string $usageType the * @return int|string */ public function usageLeftInPlanGroup($subscriberBalance, $rate, $usageType = 'call') { do { $groupSelected = $this->setNextStrongestGroup($rate, $usageType); // group not found if ($groupSelected === FALSE) { $rateUsageIncluded = 0; // @todo: add more logic instead of fallback to first $this->setPlanGroup($this->setNextStrongestGroup($rate, $usageType, true)); break; // do-while } // not group included in the specific usage try to take iterate next group if (!isset($this->data['include']['groups'][$groupSelected][$usageType])) { continue; } $rateUsageIncluded = $this->data['include']['groups'][$groupSelected][$usageType]; if (isset($this->data['include']['groups'][$groupSelected]['limits'])) { // on some cases we have limits to unlimited $limits = $this->data['include']['groups'][$groupSelected]['limits']; Billrun_Factory::dispatcher()->trigger('planGroupRule', array(&$rateUsageIncluded, &$groupSelected, $limits, $this, $usageType, $rate, $subscriberBalance)); if ($rateUsageIncluded === FALSE) { $this->unsetGroup($this->getPlanGroup()); } } } while ($groupSelected === FALSE); if ($rateUsageIncluded === 'UNLIMITED') { return PHP_INT_MAX; } if (isset($subscriberBalance['balance']['groups'][$groupSelected][$usageType]['usagev'])) { $subscriberSpent = $subscriberBalance['balance']['groups'][$groupSelected][$usageType]['usagev']; } else { $subscriberSpent = 0; } $usageLeft = $rateUsageIncluded - $subscriberSpent; return floatval($usageLeft < 0 ? 0 : $usageLeft); }
/** * method to mark all the lines that take care in the handler to avoid double runnning * * @param array $data list of items to be mark down * * @return boolean true if success */ protected function markdown(&$items) { Billrun_Factory::log()->log("Handler markdown start", Zend_Log::INFO); if (!is_array($items) || !count($items)) { Billrun_Factory::log()->log("Handler markdown items not found", Zend_Log::NOTICE); return FALSE; } Billrun_Factory::dispatcher()->trigger('beforeHandlerMarkDown', array(&$items)); foreach ($items as $plugin => &$pluginItems) { Billrun_Factory::dispatcher()->trigger('handlerMarkDown', array(&$pluginItems, $plugin, $this->options)); } Billrun_Factory::dispatcher()->trigger('afterHandlerMarkDown', array(&$items)); // TODO: check return values Billrun_Factory::log()->log("Handler markdown finished", Zend_Log::INFO); return TRUE; }
/** * execute aggregate */ public function aggregate() { Billrun_Factory::dispatcher()->trigger('beforeAggregate', array($this->data, &$this)); $account_billrun = false; $billrun_key = $this->getStamp(); $billruns_count = 0; $skipped_billruns_count = 0; if ($this->bulkAccountPreload) { Billrun_Factory::log('loading accounts that will be needed to be preloaded...', Zend_log::INFO); $dataKeys = array_keys($this->data); //$existingAccounts = array(); foreach ($dataKeys as $key => $aid) { if (!$this->overrideAccountIds && Billrun_Billrun::exists($aid, $billrun_key)) { unset($dataKeys[$key]); //$existingAccounts[$aid] = $this->data[$aid]; } } } foreach ($this->data as $accid => $account) { if ($this->memory_limit > -1 && memory_get_usage() > $this->memory_limit) { Billrun_Factory::log('Customer aggregator memory limit of ' . $this->memory_limit / 1048576 . 'M has reached. Exiting (page: ' . $this->page . ', size: ' . $this->size . ').', Zend_log::ALERT); break; } //pre-load account lines if ($this->bulkAccountPreload && !($billruns_count % $this->bulkAccountPreload) && count($dataKeys) > $billruns_count) { $aidsToLoad = array_slice($dataKeys, $billruns_count, $this->bulkAccountPreload); Billrun_Billrun::preloadAccountsLines($aidsToLoad, $billrun_key); } Billrun_Factory::dispatcher()->trigger('beforeAggregateAccount', array($accid, $account, &$this)); Billrun_Factory::log('Current account index: ' . ++$billruns_count, Zend_log::INFO); // if (!Billrun_Factory::config()->isProd()) { // if ($this->testAcc && is_array($this->testAcc) && !in_array($accid, $this->testAcc)) {//TODO : remove this?? // //Billrun_Factory::log(" Moving on nothing to see here... , account Id : $accid"); // continue; // } // } if (!$this->overrideAccountIds && Billrun_Billrun::exists($accid, $billrun_key)) { Billrun_Factory::log()->log("Billrun " . $billrun_key . " already exists for account " . $accid, Zend_Log::ALERT); $skipped_billruns_count++; continue; } $params = array('aid' => $accid, 'billrun_key' => $billrun_key, 'autoload' => !empty($this->overrideAccountIds)); $account_billrun = Billrun_Factory::billrun($params); if ($this->overrideAccountIds) { $account_billrun->resetBillrun(); } $manual_lines = array(); $deactivated_subscribers = array(); foreach ($account as $subscriber) { Billrun_Factory::dispatcher()->trigger('beforeAggregateSubscriber', array($subscriber, $account_billrun, &$this)); $sid = $subscriber->sid; if ($account_billrun->subscriberExists($sid)) { Billrun_Factory::log()->log("Billrun " . $billrun_key . " already exists for subscriber " . $sid, Zend_Log::ALERT); continue; } $next_plan_name = $subscriber->getNextPlanName(); if (is_null($next_plan_name) || $next_plan_name == "NULL") { $subscriber_status = "closed"; $current_plan_name = $subscriber->getCurrentPlanName(); if (is_null($current_plan_name) || $current_plan_name == "NULL") { Billrun_Factory::log()->log("Subscriber " . $sid . " has current plan null and next plan null", Zend_Log::INFO); $deactivated_subscribers[] = array("sid" => $sid); } } else { $subscriber_status = "open"; Billrun_Factory::log("Getting flat price for subscriber {$sid}", Zend_log::INFO); $flat_price = $subscriber->getFlatPrice(); Billrun_Factory::log("Finished getting flat price for subscriber {$sid}", Zend_log::INFO); if (is_null($flat_price)) { Billrun_Factory::log()->log("Couldn't find flat price for subscriber " . $sid . " for billrun " . $billrun_key, Zend_Log::ALERT); continue; } Billrun_Factory::log('Adding flat line to subscriber ' . $sid, Zend_Log::INFO); $flat = $this->saveFlatLine($subscriber, $billrun_key); $manual_lines = array_merge($manual_lines, array($flat['stamp'] => $flat)); Billrun_Factory::log('Finished adding flat line to subscriber ' . $sid, Zend_Log::INFO); } $manual_lines = array_merge($manual_lines, $this->saveCreditLines($subscriber, $billrun_key)); $manual_lines = array_merge($manual_lines, $this->saveServiceLines($subscriber, $billrun_key)); $account_billrun->addSubscriber($subscriber, $subscriber_status); Billrun_Factory::dispatcher()->trigger('afterAggregateSubscriber', array($subscriber, $account_billrun, &$this)); } $lines = $account_billrun->addLines($manual_lines, $deactivated_subscribers); $account_billrun->filter_disconected_subscribers($deactivated_subscribers); //save the billrun if ($account_billrun->is_deactivated() === true) { Billrun_Factory::log('deactivated account, no need for invoice ' . $accid, Zend_Log::DEBUG); continue; } Billrun_Factory::log('Saving account ' . $accid, Zend_Log::INFO); if ($account_billrun->save() === false) { Billrun_Factory::log('Error saving account ' . $accid, Zend_Log::ALERT); continue; } $this->successfulAccounts[] = $accid; Billrun_Factory::log('Finished saving account ' . $accid, Zend_Log::INFO); Billrun_Factory::dispatcher()->trigger('aggregateBeforeCloseAccountBillrun', array($accid, $account, $account_billrun, $lines, &$this)); Billrun_Factory::log("Closing billrun {$billrun_key} for account {$accid}", Zend_log::INFO); $account_billrun->close($this->min_invoice_id); Billrun_Factory::log("Finished closing billrun {$billrun_key} for account {$accid}", Zend_log::INFO); Billrun_Factory::dispatcher()->trigger('afterAggregateAccount', array($accid, $account, $account_billrun, $lines, &$this)); if ($this->bulkAccountPreload) { Billrun_Billrun::clearPreLoadedLines(array($accid)); } } if ($billruns_count == count($this->data)) { $end_msg = "Finished iterating page {$this->page} of size {$this->size}. Memory usage is " . memory_get_usage() / 1048576 . " MB\n"; $end_msg .= "Processed " . ($billruns_count - $skipped_billruns_count) . " accounts, Skipped over {$skipped_billruns_count} accounts, out of a total of {$billruns_count} accounts"; Billrun_Factory::log($end_msg, Zend_log::INFO); $this->sendEndMail($end_msg); } // @TODO trigger after aggregate Billrun_Factory::dispatcher()->trigger('afterAggregate', array($this->data, &$this)); return $this->successfulAccounts; }
/** * Receive files from the ftp host. * @param type $hostName the ftp hostname/alias * @param type $config the ftp configuration * @return array conatining the path to the received files. */ protected function receiveFromHost($hostName, $config) { $ret = array(); $files = $this->ftp->getDirectory($config['remote_directory'])->getContents(); Billrun_Factory::log()->log("FTP: Starting to receive from remote host : {$hostName}", Zend_Log::DEBUG); $count = 0; foreach ($this->sortByFileDate($files) as $file) { Billrun_Factory::log()->log("FTP: Found file " . $file->name . " on remote host", Zend_Log::DEBUG); $extraData = array(); Billrun_Factory::dispatcher()->trigger('beforeFTPFileReceived', array(&$file, $this, $hostName, &$extraData)); $isFileReceivedMoreFields = array('retrieved_from' => $hostName); if ($extraData) { $isFileReceivedMoreFields['extra_data'] = $extraData; } if (!$file->isFile()) { Billrun_Factory::log()->log("FTP: " . $file->name . " is not a file", Zend_Log::DEBUG); continue; } if (!$this->isFileValid($file->name, $file->path)) { Billrun_Factory::log()->log("FTP: " . $file->name . " is not a valid file", Zend_Log::DEBUG); continue; } if ($this->isFileReceived($file->name, static::$type, $isFileReceivedMoreFields)) { Billrun_Factory::log()->log("FTP: " . $file->name . " received already", Zend_Log::DEBUG); continue; } Billrun_Factory::log()->log("FTP: Download file " . $file->name . " from remote host", Zend_Log::INFO); $targetPath = $this->workspace; if (substr($targetPath, -1) != '/') { $targetPath .= '/'; } $targetPath .= date("Ym") . DIRECTORY_SEPARATOR . substr(md5(serialize($config)), 0, 7) . DIRECTORY_SEPARATOR; if (!file_exists($targetPath)) { mkdir($targetPath, 0777, true); } if ($file->saveToPath($targetPath, null, 0, true) === FALSE) { // the last arg declare try to recover on failure Billrun_Factory::log()->log("FTP: failed to download " . $file->name . " from remote host", Zend_Log::ALERT); continue; } $received_path = $targetPath . $file->name; if ($this->preserve_timestamps) { $timestamp = $file->getModificationTime(); if ($timestamp !== FALSE) { Billrun_Util::setFileModificationTime($received_path, $timestamp); } } Billrun_Factory::dispatcher()->trigger('afterFTPFileReceived', array(&$received_path, $file, $this, $hostName, $extraData)); if ($this->logDB($received_path, $hostName, $extraData)) { $ret[] = $received_path; $count++; //count the file as recieved // delete the file after downloading and store it to processing queue if (Billrun_Factory::config()->isProd() && (isset($config['delete_received']) && $config['delete_received'])) { Billrun_Factory::log()->log("FTP: Deleting file {$file->name} from remote host ", Zend_Log::DEBUG); $file->delete(); } } if ($count >= $this->limit) { break; } } return $ret; }
/** * execute aggregate */ public function aggregate() { if ($this->write_stamps_to_file) { if (!$this->initStampsDir()) { Billrun_Factory::log()->log("Could not create stamps file for page " . $this->page, Zend_Log::ALERT); return false; } } // @TODO trigger before aggregate Billrun_Factory::dispatcher()->trigger('beforeAggregate', array($this->data, &$this)); $account_billrun = false; $billrun_key = $this->getStamp(); $billruns_count = 0; foreach ($this->data as $accid => $account) { if ($this->memory_limit > -1 && memory_get_usage() > $this->memory_limit) { Billrun_Factory::log('Customer aggregator memory limit of ' . $this->memory_limit / 1048576 . 'M has reached. Exiting (page: ' . $this->page . ', size: ' . $this->size . ').', Zend_log::ALERT); break; } Billrun_Factory::dispatcher()->trigger('beforeAggregateAccount', array($accid, $account, &$this)); Billrun_Factory::log('Current account index: ' . ++$billruns_count, Zend_log::INFO); if (!Billrun_Factory::config()->isProd()) { if ($this->testAcc && is_array($this->testAcc) && !in_array($accid, $this->testAcc)) { //Billrun_Factory::log("Moving on nothing to see here... , account Id : $accid"); continue; } } if (Billrun_Billrun::exists($accid, $billrun_key)) { Billrun_Factory::log()->log("Billrun " . $billrun_key . " already exists for account " . $accid, Zend_Log::ALERT); continue; } $params = array('aid' => $accid, 'billrun_key' => $billrun_key, 'autoload' => false); $account_billrun = Billrun_Factory::billrun($params); $flat_lines = array(); foreach ($account as $subscriber) { Billrun_Factory::dispatcher()->trigger('beforeAggregateSubscriber', array($subscriber, $account_billrun, &$this)); $sid = $subscriber->sid; if ($account_billrun->subscriberExists($sid)) { Billrun_Factory::log()->log("Billrun " . $billrun_key . " already exists for subscriber " . $sid, Zend_Log::ALERT); continue; } $next_plan_name = $subscriber->getNextPlanName(); if (is_null($next_plan_name) || $next_plan_name == "NULL") { $subscriber_status = "closed"; } else { $subscriber_status = "open"; Billrun_Factory::log("Getting flat price for subscriber {$sid}", Zend_log::INFO); $flat_price = $subscriber->getFlatPrice(); Billrun_Factory::log("Finished getting flat price for subscriber {$sid}", Zend_log::INFO); if (is_null($flat_price)) { Billrun_Factory::log()->log("Couldn't find flat price for subscriber " . $sid . " for billrun " . $billrun_key, Zend_Log::ALERT); continue; } Billrun_Factory::log('Adding flat line to subscriber ' . $sid, Zend_Log::INFO); $flat_lines[] = $this->saveFlatLine($subscriber, $billrun_key); Billrun_Factory::log('Finished adding flat line to subscriber ' . $sid, Zend_Log::INFO); } $account_billrun->addSubscriber($subscriber, $subscriber_status); Billrun_Factory::dispatcher()->trigger('afterAggregateSubscriber', array($subscriber, $account_billrun, &$this)); } if ($this->write_stamps_to_file) { $lines = $account_billrun->addLines(false, 0, $flat_lines); if (!empty($lines)) { $stamps_str = implode("\n", array_keys($lines)) . "\n"; file_put_contents($this->file_path, $stamps_str, FILE_APPEND); } } else { $lines = $account_billrun->addLines(true, 0, $flat_lines); } //save the billrun Billrun_Factory::log('Saving account ' . $accid, Zend_Log::INFO); if ($account_billrun->save() === false) { Billrun_Factory::log('Error saving account ' . $accid, Zend_Log::ALERT); continue; } Billrun_Factory::log('Finished saving account ' . $accid, Zend_Log::INFO); Billrun_Factory::dispatcher()->trigger('aggregateBeforeCloseAccountBillrun', array($accid, $account, $account_billrun, $lines, &$this)); Billrun_Factory::log("Closing billrun {$billrun_key} for account {$accid}", Zend_log::INFO); $account_billrun->close($this->min_invoice_id); Billrun_Factory::log("Finished closing billrun {$billrun_key} for account {$accid}", Zend_log::INFO); Billrun_Factory::dispatcher()->trigger('afterAggregateAccount', array($accid, $account, $account_billrun, $lines, &$this)); } if ($billruns_count == count($this->data)) { $end_msg = "Finished iterating page {$this->page} of size {$this->size}. Memory usage is " . memory_get_usage() / 1048576 . " MB"; Billrun_Factory::log($end_msg, Zend_log::INFO); $this->sendEndMail($end_msg); } // @TODO trigger after aggregate Billrun_Factory::dispatcher()->trigger('afterAggregate', array($this->data, &$this)); }