/** * method to execute remove of billing lines (only credit and active) * it's called automatically by the api main controller */ public function execute() { Billrun_Factory::log()->log("Execute api remove", Zend_Log::INFO); $request = $this->getRequest()->getRequest(); // supports GET / POST requests Billrun_Factory::log()->log("Input: " . print_R($request, 1), Zend_Log::INFO); $stamps = array(); foreach ($request['stamps'] as $line_stamp) { $clear_stamp = Billrun_Util::filter_var($line_stamp, FILTER_SANITIZE_STRING, FILTER_FLAG_ALLOW_HEX); if (!empty($clear_stamp)) { $stamps[] = $clear_stamp; } } if (empty($stamps)) { Billrun_Factory::log()->log("remove action failed; no correct stamps", Zend_Log::INFO); $this->getController()->setOutput(array(array('status' => false, 'desc' => 'failed - invalid stamps input', 'input' => $request))); return true; } $model = new LinesModel(); $query = array('source' => 'api', 'stamp' => array('$in' => $stamps), '$or' => array(array('billrun' => array('$gte' => Billrun_Billrun::getActiveBillrun())), array('billrun' => array('$exists' => false)))); $ret = $model->remove($query); if (!isset($ret['ok']) || !$ret['ok'] || !isset($ret['n'])) { Billrun_Factory::log()->log("remove action failed pr miscomplete", Zend_Log::INFO); $this->getController()->setOutput(array(array('status' => false, 'desc' => 'remove failed', 'input' => $request))); return true; } Billrun_Factory::log()->log("remove success", Zend_Log::INFO); $this->getController()->setOutput(array(array('status' => $ret['n'], 'desc' => 'success', 'input' => $request))); }
public function load() { $this->date = date(Billrun_Base::base_dateformat, $this->now); $subscriber = Billrun_Factory::subscriber(); $this->account_data = array(); $res = $subscriber->getList(0, 1, $this->date, $this->aid); if (!empty($res)) { $this->account_data = current($res); } $previous_billrun_key = Billrun_Util::getPreviousBillrunKey($this->stamp); if (Billrun_Billrun::exists($this->aid, $previous_billrun_key)) { $start_time = 0; // maybe some lines are late (e.g. tap3) } else { $start_time = Billrun_Util::getStartTime($this->stamp); // to avoid getting lines of previous billruns } $billrun_params = array('aid' => $this->aid, 'billrun_key' => $this->stamp, 'autoload' => false); $billrun = Billrun_Factory::billrun($billrun_params); $flat_lines = array(); foreach ($this->account_data as $subscriber) { if ($billrun->subscriberExists($subscriber->sid)) { Billrun_Factory::log()->log("Billrun " . $this->stamp . " already exists for subscriber " . $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"; $flat_lines[] = new Mongodloid_Entity($subscriber->getFlatEntry($this->stamp)); } $billrun->addSubscriber($subscriber, $subscriber_status); } $this->lines = $billrun->addLines(false, $start_time, $flat_lines); $this->data = $billrun->getRawData(); }
/** * 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; }
/** * 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)); }
} /** * returns true if account has no active subscribers and no relevant lines for next billrun * @return true if account is deactivated (causes no xml to be produced for this account) */ public function is_deactivated() { $deactivated = true; foreach ($this->data['subs'] as $subscriber) { $its_empty = $this->empty_subscriber($subscriber); if (!$its_empty) { $deactivated = false; break; } } return $deactivated; } /** * checks for a given account if its "empty" : its status is closed and it has no relevant lines for next billrun * @param type $subscriber : sid * @return true if its "emtpy" */ public function empty_subscriber($subscriber) { $status = $subscriber['subscriber_status']; return $status == "closed" && !isset($subscriber['breakdown']); } } Billrun_Billrun::loadRates(); Billrun_Billrun::loadPlans();
public function __construct($options = array()) { if (isset($options['autoload'])) { $autoload = $options['autoload']; } else { $autoload = true; } $options['autoload'] = false; parent::__construct($options); if (isset($options['calculator']['limit'])) { $this->limit = $options['calculator']['limit']; } if (isset($options['calculator']['vatable'])) { $this->vatable = $options['calculator']['vatable']; } if (isset($options['calculator']['months_limit'])) { $this->months_limit = $options['calculator']['months_limit']; } if (isset($options['calculator']['unlimited_to_balances'])) { $this->unlimited_to_balances = (bool) $options['calculator']['unlimited_to_balances']; } $this->billrun_lower_bound_timestamp = is_null($this->months_limit) ? 0 : strtotime($this->months_limit . " months ago"); // set months limit if ($autoload) { $this->load(); } $this->loadRates(); $this->loadPlans(); $this->balances = Billrun_Factory::db(array('name' => 'balances'))->balancesCollection()->setReadPreference('RP_PRIMARY'); $this->active_billrun = Billrun_Billrun::getActiveBillrun(); $this->active_billrun_end_time = Billrun_Util::getEndTime($this->active_billrun); $this->next_active_billrun = Billrun_Util::getFollowingBillrunKey($this->active_billrun); // max recursive retrues for value=oldValue tactic $this->concurrentMaxRetries = (int) Billrun_Factory::config()->getConfigValue('updateValueEqualOldValueMaxRetries', 8); $this->sidsQueuedForRebalance = array_flip(Billrun_Factory::db()->rebalance_queueCollection()->distinct('sid')); }
/** * Is billrun in live mode? * @return boolean true for live, false otherwise */ public static function isLiveUpdate() { if (!isset(self::$live_update)) { self::$live_update = Billrun_Factory::config()->getConfigValue('billrun.live_update', false); } return self::$live_update; }