Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature: moved billing_calculate to a laravel command. #13021

Closed
wants to merge 9 commits into from
2 changes: 1 addition & 1 deletion .env.travis
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
APP_KEY=base64:vHI+YHgkyCDad31iPEErGSNEOWO21wNzV+zyENKQv04=
APP_URL=http://localhost:8000
APP_ENV=testing

DB_CONNECTION=sqlite
DB_HOST=127.0.0.1
DB_DATABASE=librenms_phpunit_78hunjuybybh
DB_USERNAME=root
Expand Down
162 changes: 162 additions & 0 deletions app/Console/Commands/BillingCalculate.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
<?php

namespace App\Console\Commands;

use App\Models\Bill;
use App\Models\BillHistory;
use Illuminate\Console\Command;
use LibreNMS\Util\Number;

require_once base_path() . '/includes/init.php';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry this needs to be removed

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean this line?(so this functions need also converted to laravel?

use LibreNMS\Util\Number;
require_once base_path() . '/includes/init.php';

This file is required for commands

use Illuminate\Console\Command;

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes and within there lies the pain ;)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this line be removed now?


class BillingCalculate extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'billing:calculate {--r}';

/**
* The console command description.
*
* @var string
*/
protected $description = 'calculate the port usage for the billing.';

/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}

/**
* Execute the console command.
*
* @return int
*/
public function handle()
{
if ($this->option('r')) {
$this->info("Clearing history table.\n");
BillHistory::truncate();
}
//get all bills and order by bill_id
foreach (Bill::orderBy('bill_id')->get() as $bill) {
$this->info(str_pad($bill->bill_id . ' ' . $bill->bill_name, 30) . " \n");
$i = 0;
while ($i <= 24) {
unset($class);
unset($rate_data);
$day_data = getDates($bill->bill_day, $i);

$datefrom = $day_data['0'];
$dateto = $day_data['1'];
$check = BillHistory::where(['bill_id' => $bill->bill_id, 'bill_datefrom' => $datefrom, 'bill_dateto' => $dateto])->first();
$period = getPeriod($bill['bill_id'], $datefrom, $dateto);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can port these functions to class based ones, and if they are used in other places just replace the original function with a return myNewFunction()

we done that in many places.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This exact function probably should be in a model tho

$date_updated = str_replace('-', '', str_replace(':', '', str_replace(' ', '', $check['updated'])));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

only a hint: str_replace([' ', ':', '-'], '', $check['updated']) is easier to read

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks your input! I changed this line :)

if ($period > 0 && $dateto > $date_updated) {
$rate_data = getRates($bill['bill_id'], $datefrom, $dateto, $dir_95th);
$rate_95th = $rate_data['rate_95th'];
$dir_95th = $rate_data['dir_95th'];
$total_data = $rate_data['total_data'];
$rate_average = $rate_data['rate_average'];

if ($bill['bill_type'] == 'cdr') {
$type = 'CDR';
$allowed = $bill['bill_cdr'];
$used = $rate_data['rate_95th'];
$allowed_text = Number::formatSi($allowed, 2, 3, 'bps');
$used_text = Number::formatSi($used, 2, 3, 'bps');
$overuse = ($used - $allowed);
$overuse = (($overuse <= 0) ? '0' : $overuse);
$percent = round((($rate_data['rate_95th'] / $bill['bill_cdr']) * 100), 2);
} elseif ($bill['bill_type'] == 'quota') {
$type = 'Quota';
$allowed = $bill['bill_quota'];
$used = $rate_data['total_data'];
$allowed_text = format_bytes_billing($allowed);
$used_text = format_bytes_billing($used);
$overuse = ($used - $allowed);
$overuse = (($overuse <= 0) ? '0' : $overuse);
$percent = round((($rate_data['total_data'] / $bill['bill_quota']) * 100), 2);
}

$this->info(strftime('%x @ %X', strtotime($datefrom)) . ' to ' . strftime('%x @ %X', strtotime($dateto)) . ' ' . str_pad($type, 8) . ' ' . str_pad($allowed_text, 10) . ' ' . str_pad($used_text, 10) . ' ' . $percent . '%');

if ($i == '0') {
$update = [
'rate_95th' => $rate_data['rate_95th'],
'rate_95th_in' => $rate_data['rate_95th_in'],
'rate_95th_out' => $rate_data['rate_95th_out'],
'dir_95th' => $rate_data['dir_95th'],
'total_data' => $rate_data['total_data'],
'total_data_in' => $rate_data['total_data_in'],
'total_data_out' => $rate_data['total_data_out'],
'rate_average' => $rate_data['rate_average'],
'rate_average_in' => $rate_data['rate_average_in'],
'rate_average_out' => $rate_data['rate_average_out'],
'bill_last_calc' => ['NOW()'],
];
Bill::where('bill_id', $bill->bill_id)->update($update);
$this->info('Updated!');
}
if ($check['bill_id'] == $bill['bill_id']) {
$update = [
'rate_95th' => $rate_data['rate_95th'],
'rate_95th_in' => $rate_data['rate_95th_in'],
'rate_95th_out' => $rate_data['rate_95th_out'],
'dir_95th' => $rate_data['dir_95th'],
'rate_average' => $rate_data['rate_average'],
'rate_average_in' => $rate_data['rate_average_in'],
'rate_average_out' => $rate_data['rate_average_out'],
'traf_total' => $rate_data['total_data'],
'traf_in' => $rate_data['total_data_in'],
'traf_out' => $rate_data['total_data_out'],
'bill_used' => $used,
'bill_overuse' => $overuse,
'bill_percent' => $percent,
'updated' => ['NOW()'],
];
BillHistory::where('bill_hist_id', $check->bill_hist_id)->update($update);
$this->info('Updated history!');
} else {
$update = [
'rate_95th' => $rate_data['rate_95th'],
'rate_95th_in' => $rate_data['rate_95th_in'],
'rate_95th_out' => $rate_data['rate_95th_out'],
'dir_95th' => $rate_data['dir_95th'],
'rate_average' => $rate_data['rate_average'],
'rate_average_in' => $rate_data['rate_average_in'],
'rate_average_out' => $rate_data['rate_average_out'],
'traf_total' => $rate_data['total_data'],
'traf_in' => $rate_data['total_data_in'],
'traf_out' => $rate_data['total_data_out'],
'bill_datefrom' => $datefrom,
'bill_dateto' => $dateto,
'bill_type' => $type,
'bill_allowed' => $allowed,
'bill_used' => $used,
'bill_overuse' => $overuse,
'bill_percent' => $percent,
'bill_id' => $bill['bill_id'],
];
BillHistory::insert($update);
// dbInsert($update, 'bill_history');
$this->info('Generated history!');
}//end if
echo "\n\n";
}//end if

$i++;
}
}

return 0;
}
}
14 changes: 14 additions & 0 deletions app/Models/BillHistory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class BillHistory extends Model
{
protected $table = 'bill_history';
public $timestamps = false;

use HasFactory;
}
163 changes: 37 additions & 126 deletions billing-calculate.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,135 +8,46 @@
*
* @copyright (C) 2006 - 2012 Adam Armstrong
*/
require __DIR__ . '/vendor/autoload.php';
$app = require_once __DIR__ . '/bootstrap/app.php';

use LibreNMS\Util\Number;

$init_modules = [];
require __DIR__ . '/includes/init.php';
use Illuminate\Support\Facades\Artisan;

$options = getopt('r');

$command = [$_SERVER['argv'][0], 'billing:calculate'];
if (isset($options['r'])) {
echo "Clearing history table.\n";
dbQuery('TRUNCATE TABLE `bill_history`');
array_push($command, '--r');
}

foreach (dbFetchRows('SELECT * FROM `bills` ORDER BY `bill_id`') as $bill) {
echo str_pad($bill['bill_id'] . ' ' . $bill['bill_name'], 30) . " \n";

$i = 0;
while ($i <= 24) {
unset($class);
unset($rate_data);
$day_data = getDates($bill['bill_day'], $i);

$datefrom = $day_data['0'];
$dateto = $day_data['1'];

$check = dbFetchRow('SELECT * FROM `bill_history` WHERE bill_id = ? AND bill_datefrom = ? AND bill_dateto = ? LIMIT 1', [$bill['bill_id'], $datefrom, $dateto]);

$period = getPeriod($bill['bill_id'], $datefrom, $dateto);

$date_updated = str_replace('-', '', str_replace(':', '', str_replace(' ', '', $check['updated'])));

// Send the current dir_95th to the getRates function so it knows to aggregate or return the max in/out value and highest direction
$dir_95th = $bill['dir_95th'];

if ($period > 0 && $dateto > $date_updated) {
$rate_data = getRates($bill['bill_id'], $datefrom, $dateto, $dir_95th);
$rate_95th = $rate_data['rate_95th'];
$dir_95th = $rate_data['dir_95th'];
$total_data = $rate_data['total_data'];
$rate_average = $rate_data['rate_average'];

if ($bill['bill_type'] == 'cdr') {
$type = 'CDR';
$allowed = $bill['bill_cdr'];
$used = $rate_data['rate_95th'];
$allowed_text = Number::formatSi($allowed, 2, 3, 'bps');
$used_text = Number::formatSi($used, 2, 3, 'bps');
$overuse = ($used - $allowed);
$overuse = (($overuse <= 0) ? '0' : $overuse);
$percent = round((($rate_data['rate_95th'] / $bill['bill_cdr']) * 100), 2);
} elseif ($bill['bill_type'] == 'quota') {
$type = 'Quota';
$allowed = $bill['bill_quota'];
$used = $rate_data['total_data'];
$allowed_text = format_bytes_billing($allowed);
$used_text = format_bytes_billing($used);
$overuse = ($used - $allowed);
$overuse = (($overuse <= 0) ? '0' : $overuse);
$percent = round((($rate_data['total_data'] / $bill['bill_quota']) * 100), 2);
}

echo strftime('%x @ %X', strtotime($datefrom)) . ' to ' . strftime('%x @ %X', strtotime($dateto)) . ' ' . str_pad($type, 8) . ' ' . str_pad($allowed_text, 10) . ' ' . str_pad($used_text, 10) . ' ' . $percent . '%';

if ($i == '0') {
$update = [
'rate_95th' => $rate_data['rate_95th'],
'rate_95th_in' => $rate_data['rate_95th_in'],
'rate_95th_out' => $rate_data['rate_95th_out'],
'dir_95th' => $rate_data['dir_95th'],
'total_data' => $rate_data['total_data'],
'total_data_in' => $rate_data['total_data_in'],
'total_data_out' => $rate_data['total_data_out'],
'rate_average' => $rate_data['rate_average'],
'rate_average_in' => $rate_data['rate_average_in'],
'rate_average_out' => $rate_data['rate_average_out'],
'bill_last_calc' => ['NOW()'],
];

dbUpdate($update, 'bills', '`bill_id` = ?', [$bill['bill_id']]);
echo ' Updated! ';
}

if ($check['bill_id'] == $bill['bill_id']) {
$update = [
'rate_95th' => $rate_data['rate_95th'],
'rate_95th_in' => $rate_data['rate_95th_in'],
'rate_95th_out' => $rate_data['rate_95th_out'],
'dir_95th' => $rate_data['dir_95th'],
'rate_average' => $rate_data['rate_average'],
'rate_average_in' => $rate_data['rate_average_in'],
'rate_average_out' => $rate_data['rate_average_out'],
'traf_total' => $rate_data['total_data'],
'traf_in' => $rate_data['total_data_in'],
'traf_out' => $rate_data['total_data_out'],
'bill_used' => $used,
'bill_overuse' => $overuse,
'bill_percent' => $percent,
'updated' => ['NOW()'],
];

dbUpdate($update, 'bill_history', '`bill_hist_id` = ?', [$check['bill_hist_id']]);
echo ' Updated history! ';
} else {
$update = [
'rate_95th' => $rate_data['rate_95th'],
'rate_95th_in' => $rate_data['rate_95th_in'],
'rate_95th_out' => $rate_data['rate_95th_out'],
'dir_95th' => $rate_data['dir_95th'],
'rate_average' => $rate_data['rate_average'],
'rate_average_in' => $rate_data['rate_average_in'],
'rate_average_out' => $rate_data['rate_average_out'],
'traf_total' => $rate_data['total_data'],
'traf_in' => $rate_data['total_data_in'],
'traf_out' => $rate_data['total_data_out'],
'bill_datefrom' => $datefrom,
'bill_dateto' => $dateto,
'bill_type' => $type,
'bill_allowed' => $allowed,
'bill_used' => $used,
'bill_overuse' => $overuse,
'bill_percent' => $percent,
'bill_id' => $bill['bill_id'],
];
dbInsert($update, 'bill_history');
echo ' Generated history! ';
}//end if
echo "\n\n";
}//end if

$i++;
}//end while
}//end foreach
// Check that we don't run this as the wrong user and break the install
\App\Checks::runningUser();
/*
|--------------------------------------------------------------------------
| Run The Artisan Application
|--------------------------------------------------------------------------
|
| When we run the console application, the current CLI command will be
| executed in this console and the response sent back to a terminal
| or another output device for the developers. Here goes nothing!
|
*/
$kernel = $app->make(Illuminate\Contracts\Console\Kernel::class);
$status = $kernel->handle(
$input = new Symfony\Component\Console\Input\ArgvInput($command),
new Symfony\Component\Console\Output\ConsoleOutput
);

/*
|--------------------------------------------------------------------------
| Shutdown The Application
|--------------------------------------------------------------------------
|
| Once Artisan has finished running, we will fire off the shutdown events
| so that any final work may be done by the application before we shut
| down the process. This is the last thing to happen to the request.
|
*/

$kernel->terminate($input, $status);

exit($status);