mirror of
https://github.com/snipe/snipe-it.git
synced 2024-12-23 12:44:12 -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()
|
||||
{
|
||||
$filename = $this->argument('filename');
|
||||
$importerClass = Importer::class;
|
||||
switch (strtolower($this->option('item-type'))) {
|
||||
case "asset":
|
||||
$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(
|
||||
$class = title_case($this->option('item-type'));
|
||||
$classString = "App\\Importer\\{$class}Importer";
|
||||
$importer = new $classString(
|
||||
$filename,
|
||||
[$this, 'log'],
|
||||
[$this, 'progress'],
|
||||
|
|
|
@ -812,6 +812,9 @@ class AssetsController extends Controller
|
|||
case "consumable":
|
||||
$redirectTo = "consumables.index";
|
||||
break;
|
||||
case "component":
|
||||
$redirectTo = "components.index";
|
||||
break;
|
||||
}
|
||||
|
||||
if ($errors) { //Failure
|
||||
|
|
|
@ -31,25 +31,11 @@ class ItemImportRequest extends FormRequest
|
|||
|
||||
public function import()
|
||||
{
|
||||
$filename = config('app.private_uploads') . '/imports/assets/' . $this->get('filename');
|
||||
|
||||
$importerClass = Importer::class;
|
||||
switch ($this->get('import-type')) {
|
||||
case "asset":
|
||||
$importerClass = 'App\Importer\AssetImporter';
|
||||
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 = config('app.private_uploads') . '/imports/assets/' . $this->get('filename');
|
||||
$class = title_case($this->input('import-type'));
|
||||
$classString = "App\\Importer\\{$class}Importer";
|
||||
$importer = new $classString(
|
||||
$filename,
|
||||
[$this, 'log'],
|
||||
[$this, 'progress'],
|
||||
|
|
|
@ -40,7 +40,7 @@ class AccessoryImporter extends ItemImporter
|
|||
$accessory = $this->accessories->search(function ($key) {
|
||||
return strcasecmp($key->name, $this->item['item_name']) == 0;
|
||||
});
|
||||
if ($accessory) {
|
||||
if ($accessory !== false) {
|
||||
$editingAccessory = true;
|
||||
if (!$this->updating) {
|
||||
$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) {
|
||||
return strcasecmp($key->asset_tag, $this->item['asset_tag']) == 0;
|
||||
});
|
||||
if ($asset) {
|
||||
if ($asset !== false) {
|
||||
$editingAsset = true;
|
||||
if (!$this->updating) {
|
||||
$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) {
|
||||
return strcasecmp($key->name, $this->item['item_name']) == 0;
|
||||
});
|
||||
if ($consumable) {
|
||||
if ($consumable !== false) {
|
||||
$editingConsumable = true;
|
||||
if (!$this->updating) {
|
||||
$this->log('A matching Consumable ' . $this->item["item_name"] . ' already exists. ');
|
||||
|
|
|
@ -78,7 +78,7 @@ abstract class Importer
|
|||
$updating = false,
|
||||
$usernameFormat = null
|
||||
) {
|
||||
|
||||
|
||||
$this->filename = $filename;
|
||||
$this->csv = Reader::createFromPath($filename);
|
||||
$this->csv->setNewLine('\r\n');
|
||||
|
|
|
@ -138,7 +138,7 @@ class ItemImporter extends Importer
|
|||
public function createOrFetchCategory($asset_category)
|
||||
{
|
||||
// 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')));
|
||||
if (empty($asset_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.
|
||||
// This casts to false and causes false positives
|
||||
if ($category !== false) {
|
||||
$this->log("A matching category: " . $asset_category . " already exists");
|
||||
return $this->categories[$category];
|
||||
}
|
||||
|
||||
|
|
|
@ -97,7 +97,7 @@
|
|||
<i class="fa fa-plus icon-white"></i>
|
||||
<span>Select Import File...</span>
|
||||
<!-- 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>
|
||||
</div>
|
||||
<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::post('import', 'AssetsController@postAPIImportUpload');
|
||||
Route::post('import', [ 'as' => 'api.hardware.importFile', 'uses'=> 'AssetsController@postAPIImportUpload']);
|
||||
});
|
||||
|
||||
/*---Status Label API---*/
|
||||
|
|
Loading…
Reference in a new issue