De-normalize new counters from 4.3.0 (#5547)

* Added de-norm counter migration for assets

* Renaming counter columns, since Eloquent has a magical *_count helper

* Added artisan command to sync counters (one-off)

* Update API to use de-normed fields

* Increment counters for checkin;/checkout

* Derp.

* Added request increment/decrementer

* Move increment for checkout to the Asset::checkout method

* Added “could take a while” message
This commit is contained in:
snipe 2018-05-16 19:20:43 -07:00 committed by GitHub
parent 87c6ee2035
commit 4c656c0321
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 172 additions and 12 deletions

View file

@ -0,0 +1,76 @@
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use App\Models\Asset;
class SyncAssetCounters extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'snipeit:counter-sync';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Syncs checkedout, checked in, and requested counters for assets';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
$start = microtime(true);
$assets = Asset::withCount('checkins', 'checkouts', 'userRequests')
->withTrashed()->get();
if ($assets) {
if ($assets->count() > 0) {
$bar = $this->output->createProgressBar($assets->count());
foreach ($assets as $asset) {
$asset->checkin_counter = (int) $asset->checkins_count;
$asset->checkout_counter = (int) $asset->checkouts_count;
$asset->requests_counter = (int) $asset->user_requests_count;
$asset->unsetEventDispatcher();
$asset->save();
$output['info'][] = 'Asset: ' . $asset->id . ' has ' . $asset->checkin_counter . ' checkins, ' . $asset->checkout_counter . ' checkouts, and ' . $asset->requests_counter . ' requests';
$bar->advance();
}
$bar->finish();
foreach ($output['info'] as $key => $output_text) {
$this->info($output_text);
}
$time_elapsed_secs = microtime(true) - $start;
$this->info('Sync executed in ' . $time_elapsed_secs . ' seconds');
} else {
$this->info('No assets to sync');
}
}
}
}

View file

@ -29,6 +29,7 @@ class Kernel extends ConsoleKernel
Commands\ResetDemoSettings::class,
Commands\SyncAssetLocations::class,
Commands\RegenerateAssetTags::class,
Commands\SyncAssetCounters::class,
];
/**

View file

@ -77,9 +77,9 @@ class AssetsController extends Controller
'last_audit_date',
'next_audit_date',
'warranty_months',
'checkouts_count',
'checkins_count',
'user_requests_count',
'checkout_counter',
'checkin_counter',
'requests_counter',
];
$filter = array();
@ -95,7 +95,7 @@ class AssetsController extends Controller
$assets = Company::scopeCompanyables(Asset::select('assets.*'),"company_id","assets")
->with('location', 'assetstatus', 'assetlog', 'company', 'defaultLoc','assignedTo',
'model.category', 'model.manufacturer', 'model.fieldset','supplier')->withCount('checkins', 'checkouts', 'userRequests');
'model.category', 'model.manufacturer', 'model.fieldset','supplier');
// These are used by the API to query against specific ID numbers.

View file

@ -181,6 +181,8 @@ class ViewAssetsController extends Controller
// If it's already requested, cancel the request.
if ($asset->isRequestedBy(Auth::user())) {
$asset->cancelRequest();
$asset->decrement('requests_counter', 1);
$logaction->logaction('request canceled');
$settings->notify(new RequestAssetCancelationNotification($data));
return redirect()->route('requestable-assets')
@ -188,8 +190,8 @@ class ViewAssetsController extends Controller
} else {
$logaction->logaction('requested');
$asset->request();
$asset->increment('requests_counter', 1);
$settings->notify(new RequestAssetNotification($data));

View file

@ -77,9 +77,9 @@ class AssetsTransformer
'last_checkout' => Helper::getFormattedDateObject($asset->last_checkout, 'datetime'),
'expected_checkin' => Helper::getFormattedDateObject($asset->expected_checkin, 'date'),
'purchase_cost' => Helper::formatCurrencyOutput($asset->purchase_cost),
'checkins_count' => (int) $asset->checkins_count,
'checkouts_count' => (int) $asset->checkouts_count,
'user_requests_count' => (int) $asset->user_requests_count,
'checkin_counter' => (int) $asset->checkin_counter,
'checkout_counter' => (int) $asset->checkout_counter,
'requests_counter' => (int) $asset->requests_counter,
'user_can_checkout' => (bool) $asset->availableForCheckout(),
];

View file

@ -199,6 +199,8 @@ class Asset extends Depreciable
if ($this->save()) {
$this->logCheckout($note, $target);
\Log::debug('Increment the checkout count for asset: '.$this->id);
$this->increment('checkout_counter', 1);
return true;
}
return false;

View file

@ -55,7 +55,7 @@ trait Loggable
if ($log->target_type == Location::class) {
$log->location_id = $target->id;
} elseif ($log->target_type == Asset::class) {
$log->location_id = $target->rtd_location_id;
$log->location_id = $target->location_id;
} else {
$log->location_id = $target->location_id;
}
@ -121,8 +121,17 @@ trait Loggable
$log->item_type = License::class;
$log->item_id = $this->license_id;
} else {
$log->item_type = static::class;
$log->item_id = $this->id;
if (static::class == Asset::class) {
if ($asset = Asset::find($log->item_id)) {
\Log::debug('Increment the checkin count for asset: '.$log->item_id);
$asset->increment('checkin_counter', 1);
}
}
}

View file

@ -182,21 +182,21 @@ class AssetPresenter extends Presenter
"title" => trans('general.notes'),
], [
"field" => "checkouts_count",
"field" => "checkout_counter",
"searchable" => false,
"sortable" => true,
"visible" => false,
"title" => trans('general.checkouts_count')
],[
"field" => "checkins_count",
"field" => "checkin_counter",
"searchable" => false,
"sortable" => true,
"visible" => false,
"title" => trans('general.checkins_count')
], [
"field" => "user_requests_count",
"field" => "requests_counter",
"searchable" => false,
"sortable" => true,
"visible" => false,

View file

@ -0,0 +1,36 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class DenormCountersOnAssets extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('assets', function (Blueprint $table) {
$table->integer('checkin_counter')->default(0);
$table->integer('checkout_counter')->default(0);
$table->integer('requests_counter')->default(0);
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('assets', function (Blueprint $table) {
$table->dropColumn('checkin_counter');
$table->dropColumn('checkout_counter');
$table->dropColumn('requests_counter');
});
}
}

View file

@ -0,0 +1,34 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
use App\Models\Asset;
class AddFirstCounterTotalsToAssets extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
// This artisan call may take a while
\Log::info('This could take a while.... ');
Artisan::call('snipeit:counter-sync');
$output = Artisan::output();
\Log::info($output);
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
//
}
}