mirror of
https://github.com/snipe/snipe-it.git
synced 2025-01-11 05:47:28 -08:00
Component Importer and various Importer Fixes (#3132)
* Importer fix: we were trimming the wrong part of the classname when creating a category. This led to categories not being recognized. * Add a component importer. Uses same fields as consumable importer. Only trick: If an asset_tag is present, we checkout a component to that asset on import Enable component importer. Also calculate the importer classname in a cleaner fashion. * Fix comparisons. find can return an index of 0, which is falsy.
This commit is contained in:
parent
816d2fd095
commit
6ce20c32b1
|
@ -68,23 +68,9 @@ class ObjectImportCommand extends Command
|
||||||
public function fire()
|
public function fire()
|
||||||
{
|
{
|
||||||
$filename = $this->argument('filename');
|
$filename = $this->argument('filename');
|
||||||
$importerClass = Importer::class;
|
$class = title_case($this->option('item-type'));
|
||||||
switch (strtolower($this->option('item-type'))) {
|
$classString = "App\\Importer\\{$class}Importer";
|
||||||
case "asset":
|
$importer = new $classString(
|
||||||
$importerClass = AssetImporter::class;
|
|
||||||
break;
|
|
||||||
case "accessory":
|
|
||||||
$importerClass = AccessoryImporter::class;
|
|
||||||
break;
|
|
||||||
case "component":
|
|
||||||
die("This is not implemented yet");
|
|
||||||
$importerClass = ComponentImporter::class;
|
|
||||||
break;
|
|
||||||
case "consumable":
|
|
||||||
$importerClass = ConsumableImporter::class;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
$importer = new $importerClass(
|
|
||||||
$filename,
|
$filename,
|
||||||
[$this, 'log'],
|
[$this, 'log'],
|
||||||
[$this, 'progress'],
|
[$this, 'progress'],
|
||||||
|
|
|
@ -812,6 +812,9 @@ class AssetsController extends Controller
|
||||||
case "consumable":
|
case "consumable":
|
||||||
$redirectTo = "consumables.index";
|
$redirectTo = "consumables.index";
|
||||||
break;
|
break;
|
||||||
|
case "component":
|
||||||
|
$redirectTo = "components.index";
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($errors) { //Failure
|
if ($errors) { //Failure
|
||||||
|
|
|
@ -31,25 +31,11 @@ class ItemImportRequest extends FormRequest
|
||||||
|
|
||||||
public function import()
|
public function import()
|
||||||
{
|
{
|
||||||
$filename = config('app.private_uploads') . '/imports/assets/' . $this->get('filename');
|
|
||||||
|
|
||||||
$importerClass = Importer::class;
|
$filename = config('app.private_uploads') . '/imports/assets/' . $this->get('filename');
|
||||||
switch ($this->get('import-type')) {
|
$class = title_case($this->input('import-type'));
|
||||||
case "asset":
|
$classString = "App\\Importer\\{$class}Importer";
|
||||||
$importerClass = 'App\Importer\AssetImporter';
|
$importer = new $classString(
|
||||||
break;
|
|
||||||
case "accessory":
|
|
||||||
$importerClass = 'App\Importer\AccessoryImporter';
|
|
||||||
break;
|
|
||||||
case "component":
|
|
||||||
die("This is not implemented yet");
|
|
||||||
$importerClass = ComponentImporter::class;
|
|
||||||
break;
|
|
||||||
case "consumable":
|
|
||||||
$importerClass = 'App\Importer\ConsumableImporter';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
$importer = new $importerClass(
|
|
||||||
$filename,
|
$filename,
|
||||||
[$this, 'log'],
|
[$this, 'log'],
|
||||||
[$this, 'progress'],
|
[$this, 'progress'],
|
||||||
|
|
|
@ -40,7 +40,7 @@ class AccessoryImporter extends ItemImporter
|
||||||
$accessory = $this->accessories->search(function ($key) {
|
$accessory = $this->accessories->search(function ($key) {
|
||||||
return strcasecmp($key->name, $this->item['item_name']) == 0;
|
return strcasecmp($key->name, $this->item['item_name']) == 0;
|
||||||
});
|
});
|
||||||
if ($accessory) {
|
if ($accessory !== false) {
|
||||||
$editingAccessory = true;
|
$editingAccessory = true;
|
||||||
if (!$this->updating) {
|
if (!$this->updating) {
|
||||||
$this->log('A matching Accessory ' . $this->item["item_name"] . ' already exists. ');
|
$this->log('A matching Accessory ' . $this->item["item_name"] . ' already exists. ');
|
||||||
|
|
|
@ -51,7 +51,7 @@ class AssetImporter extends ItemImporter
|
||||||
$asset = $this->assets->search(function ($key) {
|
$asset = $this->assets->search(function ($key) {
|
||||||
return strcasecmp($key->asset_tag, $this->item['asset_tag']) == 0;
|
return strcasecmp($key->asset_tag, $this->item['asset_tag']) == 0;
|
||||||
});
|
});
|
||||||
if ($asset) {
|
if ($asset !== false) {
|
||||||
$editingAsset = true;
|
$editingAsset = true;
|
||||||
if (!$this->updating) {
|
if (!$this->updating) {
|
||||||
$this->log('A matching Asset ' . $this->item['asset_tag'] . ' already exists');
|
$this->log('A matching Asset ' . $this->item['asset_tag'] . ' already exists');
|
||||||
|
|
114
app/Importer/ComponentImporter.php
Normal file
114
app/Importer/ComponentImporter.php
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Created by PhpStorm.
|
||||||
|
* User: parallelgrapefruit
|
||||||
|
* Date: 12/24/16
|
||||||
|
* Time: 1:03 PM
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Importer;
|
||||||
|
|
||||||
|
use App\Helpers\Helper;
|
||||||
|
use App\Models\Asset;
|
||||||
|
use App\Models\Component;
|
||||||
|
|
||||||
|
class ComponentImporter extends ItemImporter
|
||||||
|
{
|
||||||
|
protected $components;
|
||||||
|
function __construct($filename, $logCallback, $progressCallback, $errorCallback, $testRun = false, $user_id = -1, $updating = false, $usernameFormat = null)
|
||||||
|
{
|
||||||
|
parent::__construct($filename, $logCallback, $progressCallback, $errorCallback, $testRun, $user_id, $updating, $usernameFormat);
|
||||||
|
$this->components = Component::all();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function handle($row)
|
||||||
|
{
|
||||||
|
parent::handle($row); // TODO: Change the autogenerated stub
|
||||||
|
$this->createComponentIfNotExists();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a component if a duplicate does not exist
|
||||||
|
*
|
||||||
|
* @author Daniel Melzter
|
||||||
|
* @since 3.0
|
||||||
|
*/
|
||||||
|
public function createComponentIfNotExists()
|
||||||
|
{
|
||||||
|
$component = null;
|
||||||
|
$editingComponent = false;
|
||||||
|
$this->log("Creating Component");
|
||||||
|
$component = $this->components->search(function ($key) {
|
||||||
|
return strcasecmp($key->name, $this->item['item_name']) == 0;
|
||||||
|
});
|
||||||
|
if ($component !== false) {
|
||||||
|
$editingComponent = true;
|
||||||
|
if (!$this->updating) {
|
||||||
|
$this->log('A matching Component ' . $this->item["item_name"] . ' already exists. ');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$this->log("No matching component, creating one");
|
||||||
|
$component = new Component();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$editingComponent) {
|
||||||
|
$component->name = $this->item["item_name"];
|
||||||
|
}
|
||||||
|
if (!empty($this->item["purchase_date"])) {
|
||||||
|
$component->purchase_date = $this->item["purchase_date"];
|
||||||
|
} else {
|
||||||
|
$component->purchase_date = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($this->item["purchase_cost"])) {
|
||||||
|
$component->purchase_cost = Helper::ParseFloat($this->item["purchase_cost"]);
|
||||||
|
}
|
||||||
|
if (isset($this->item["location"])) {
|
||||||
|
$component->location_id = $this->item["location"]->id;
|
||||||
|
}
|
||||||
|
$component->user_id = $this->user_id;
|
||||||
|
if (isset($this->item["company"])) {
|
||||||
|
$component->company_id = $this->item["company"]->id;
|
||||||
|
}
|
||||||
|
if (!empty($this->item["order_number"])) {
|
||||||
|
$component->order_number = $this->item["order_number"];
|
||||||
|
}
|
||||||
|
if (isset($this->item["category"])) {
|
||||||
|
$component->category_id = $this->item["category"]->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO:Implement
|
||||||
|
//$component->notes= e($this->item_notes);
|
||||||
|
if (!empty($this->item["requestable"])) {
|
||||||
|
$component->requestable = filter_var($this->item["requestable"], FILTER_VALIDATE_BOOLEAN);
|
||||||
|
}
|
||||||
|
|
||||||
|
$component->qty = 1;
|
||||||
|
if ( (!empty($this->item["quantity"])) && ($this->item["quantity"] > -1)) {
|
||||||
|
$component->qty = $this->item["quantity"];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->testRun) {
|
||||||
|
$this->log('TEST RUN - Component ' . $this->item['item_name'] . ' not created');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ($component->save()) {
|
||||||
|
$component->logCreate('Imported using CSV Importer');
|
||||||
|
$this->log("Component " . $this->item["item_name"] . ' was created');
|
||||||
|
|
||||||
|
// If we have an asset tag, checkout to that asset.
|
||||||
|
if(isset($this->item['asset_tag']) && ($asset = Asset::where('asset_tag', $this->item['asset_tag'])->first()) ) {
|
||||||
|
$component->assets()->attach($component->id, [
|
||||||
|
'component_id' => $component->id,
|
||||||
|
'user_id' => $this->user_id,
|
||||||
|
'created_at' => date('Y-m-d H:i:s'),
|
||||||
|
'assigned_qty' => 1, // Only assign the first one to the asset
|
||||||
|
'asset_id' => $asset->id
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$this->jsonError($component, 'Component', $component->getErrors());
|
||||||
|
}
|
||||||
|
}
|
|
@ -40,7 +40,7 @@ class ConsumableImporter extends ItemImporter
|
||||||
$consumable = $this->consumables->search(function ($key) {
|
$consumable = $this->consumables->search(function ($key) {
|
||||||
return strcasecmp($key->name, $this->item['item_name']) == 0;
|
return strcasecmp($key->name, $this->item['item_name']) == 0;
|
||||||
});
|
});
|
||||||
if ($consumable) {
|
if ($consumable !== false) {
|
||||||
$editingConsumable = true;
|
$editingConsumable = true;
|
||||||
if (!$this->updating) {
|
if (!$this->updating) {
|
||||||
$this->log('A matching Consumable ' . $this->item["item_name"] . ' already exists. ');
|
$this->log('A matching Consumable ' . $this->item["item_name"] . ' already exists. ');
|
||||||
|
|
|
@ -78,7 +78,7 @@ abstract class Importer
|
||||||
$updating = false,
|
$updating = false,
|
||||||
$usernameFormat = null
|
$usernameFormat = null
|
||||||
) {
|
) {
|
||||||
|
|
||||||
$this->filename = $filename;
|
$this->filename = $filename;
|
||||||
$this->csv = Reader::createFromPath($filename);
|
$this->csv = Reader::createFromPath($filename);
|
||||||
$this->csv->setNewLine('\r\n');
|
$this->csv->setNewLine('\r\n');
|
||||||
|
|
|
@ -138,7 +138,7 @@ class ItemImporter extends Importer
|
||||||
public function createOrFetchCategory($asset_category)
|
public function createOrFetchCategory($asset_category)
|
||||||
{
|
{
|
||||||
// Magic to transform "AssetImporter" to "asset" or similar.
|
// Magic to transform "AssetImporter" to "asset" or similar.
|
||||||
$classname = get_class($this);
|
$classname = class_basename(get_class($this));
|
||||||
$item_type = strtolower(substr($classname, 0, strpos($classname, 'Importer')));
|
$item_type = strtolower(substr($classname, 0, strpos($classname, 'Importer')));
|
||||||
if (empty($asset_category)) {
|
if (empty($asset_category)) {
|
||||||
$asset_category = 'Unnamed Category';
|
$asset_category = 'Unnamed Category';
|
||||||
|
@ -150,6 +150,7 @@ class ItemImporter extends Importer
|
||||||
// We need strict compare here because the index returned above can be 0.
|
// We need strict compare here because the index returned above can be 0.
|
||||||
// This casts to false and causes false positives
|
// This casts to false and causes false positives
|
||||||
if ($category !== false) {
|
if ($category !== false) {
|
||||||
|
$this->log("A matching category: " . $asset_category . " already exists");
|
||||||
return $this->categories[$category];
|
return $this->categories[$category];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -97,7 +97,7 @@
|
||||||
<i class="fa fa-plus icon-white"></i>
|
<i class="fa fa-plus icon-white"></i>
|
||||||
<span>Select Import File...</span>
|
<span>Select Import File...</span>
|
||||||
<!-- The file input field used as target for the file upload widget -->
|
<!-- The file input field used as target for the file upload widget -->
|
||||||
<input id="fileupload" type="file" name="files[]" data-url="{{ url('/') }}/api/hardware/import" accept="text/csv">
|
<input id="fileupload" type="file" name="files[]" data-url="{{ route('api.hardware.importFile') }}" accept="text/csv">
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-9" id="progress-container" style="visibility: hidden; padding-bottom: 20px;">
|
<div class="col-md-9" id="progress-container" style="visibility: hidden; padding-bottom: 20px;">
|
||||||
|
|
|
@ -23,7 +23,7 @@ Route::group(['prefix' => 'v1', 'middleware' => 'auth:api'], function () {
|
||||||
|
|
||||||
Route::get('list/{status?}', [ 'as' => 'api.hardware.list', 'uses' => 'AssetsController@getDatatable' ]);
|
Route::get('list/{status?}', [ 'as' => 'api.hardware.list', 'uses' => 'AssetsController@getDatatable' ]);
|
||||||
|
|
||||||
Route::post('import', 'AssetsController@postAPIImportUpload');
|
Route::post('import', [ 'as' => 'api.hardware.importFile', 'uses'=> 'AssetsController@postAPIImportUpload']);
|
||||||
});
|
});
|
||||||
|
|
||||||
/*---Status Label API---*/
|
/*---Status Label API---*/
|
||||||
|
|
Loading…
Reference in a new issue