Skip to content

Commit

Permalink
Merge pull request #15802 from snipe/features/import_models
Browse files Browse the repository at this point in the history
Ability to import asset models (separate from assets)
  • Loading branch information
snipe authored Nov 13, 2024
2 parents ab2e7a3 + 7ccbc60 commit 3c08760
Show file tree
Hide file tree
Showing 24 changed files with 567 additions and 42 deletions.
8 changes: 6 additions & 2 deletions app/Http/Controllers/Api/AssetModelsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ public function index(Request $request) : JsonResponse | array
'model_number',
'min_amt',
'eol',
'created_by',
'requestable',
'models.notes',
'models.created_at',
Expand All @@ -69,7 +70,7 @@ public function index(Request $request) : JsonResponse | array
'models.deleted_at',
'models.updated_at',
])
->with('category', 'depreciation', 'manufacturer', 'fieldset.fields.defaultValues','adminuser')
->with('category', 'depreciation', 'manufacturer', 'fieldset.fields.defaultValues', 'adminuser')
->withCount('assets as assets_count');

if ($request->input('status')=='deleted') {
Expand All @@ -95,7 +96,7 @@ public function index(Request $request) : JsonResponse | array
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
$sort = in_array($request->input('sort'), $allowed_columns) ? $request->input('sort') : 'models.created_at';

switch ($sort) {
switch ($request->input('sort')) {
case 'manufacturer':
$assetmodels->OrderManufacturer($order);
break;
Expand All @@ -105,6 +106,9 @@ public function index(Request $request) : JsonResponse | array
case 'fieldset':
$assetmodels->OrderFieldset($order);
break;
case 'created_by':
$assetmodels->OrderByCreatedByName($order);
break;
default:
$assetmodels->orderBy($sort, $order);
break;
Expand Down
8 changes: 5 additions & 3 deletions app/Http/Controllers/Api/ImportController.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@ class ImportController extends Controller
public function index() : JsonResponse | array
{
$this->authorize('import');
$imports = Import::latest()->get();

$imports = Import::with('adminuser')->latest()->get();
return (new ImportsTransformer)->transformImports($imports);
}

Expand Down Expand Up @@ -133,7 +132,7 @@ public function store() : JsonResponse
}

$import->filesize = filesize($path.'/'.$file_name);

$import->created_by = auth()->id();
$import->save();
$results[] = $import;
}
Expand Down Expand Up @@ -177,6 +176,9 @@ public function process(ItemImportRequest $request, $import_id) : JsonResponse
case 'asset':
$redirectTo = 'hardware.index';
break;
case 'assetModel':
$redirectTo = 'models.index';
break;
case 'accessory':
$redirectTo = 'accessories.index';
break;
Expand Down
5 changes: 3 additions & 2 deletions app/Http/Requests/ItemImportRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,11 @@ public function import(Import $import)

$filename = config('app.private_uploads').'/imports/'.$import->file_path;
$import->import_type = $this->input('import-type');
$class = title_case($import->import_type);
$class = ucfirst($import->import_type);
$classString = "App\\Importer\\{$class}Importer";
$importer = new $classString($filename);
$import->field_map = request('column-mappings');
$import->created_by = auth()->id();
$import->save();
$fieldMappings = [];

Expand All @@ -60,7 +61,7 @@ public function import(Import $import)
$fieldMappings = array_change_key_case(array_flip($import->field_map), CASE_LOWER);
}
$importer->setCallbacks([$this, 'log'], [$this, 'progress'], [$this, 'errorCallback'])
->setUserId(auth()->id())
->setCreatedBy(auth()->id())
->setUpdating($this->get('import-update'))
->setShouldNotify($this->get('send-welcome'))
->setUsernameFormat('firstname.lastname')
Expand Down
4 changes: 4 additions & 0 deletions app/Http/Transformers/AssetModelsTransformer.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ public function transformAssetModel(AssetModel $assetmodel)
'eol' => ($assetmodel->eol > 0) ? $assetmodel->eol.' months' : 'None',
'requestable' => ($assetmodel->requestable == '1') ? true : false,
'notes' => Helper::parseEscapedMarkedownInline($assetmodel->notes),
'created_by' => ($assetmodel->adminuser) ? [
'id' => (int) $assetmodel->adminuser->id,
'name'=> e($assetmodel->adminuser->present()->fullName()),
] : null,
'created_at' => Helper::getFormattedDateObject($assetmodel->created_at, 'datetime'),
'updated_at' => Helper::getFormattedDateObject($assetmodel->updated_at, 'datetime'),
'deleted_at' => Helper::getFormattedDateObject($assetmodel->deleted_at, 'datetime'),
Expand Down
1 change: 1 addition & 0 deletions app/Importer/AccessoryImporter.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ public function createAccessoryIfNotExists($row)
}
$this->log('No Matching Accessory, Creating a new one');
$accessory = new Accessory();
$accessory->created_by = auth()->id();
$this->item['model_number'] = $this->findCsvMatch($row, "model_number");
$this->item['min_amt'] = $this->findCsvMatch($row, "min_amt");
$accessory->fill($this->sanitizeItemForStoring($accessory));
Expand Down
174 changes: 174 additions & 0 deletions app/Importer/AssetModelImporter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
<?php

namespace App\Importer;

use App\Models\AssetModel;
use App\Models\Depreciation;
use App\Models\CustomFieldset;
use Illuminate\Support\Facades\Log;

/**
* When we are importing users via an Asset/etc import, we use createOrFetchUser() in
* Importer\Importer.php. [ALG]
*
* Class LocationImporter
*/
class AssetModelImporter extends ItemImporter
{
protected $models;

public function __construct($filename)
{
parent::__construct($filename);
}

protected function handle($row)
{
parent::handle($row);
$this->createAssetModelIfNotExists($row);
}

/**
* Create a model if a duplicate does not exist.
* @todo Investigate how this should interact with Importer::createModelIfNotExists
*
* @author A. Gianotto
* @since 6.1.0
* @param array $row
*/
public function createAssetModelIfNotExists(array $row)
{

$editingAssetModel = false;
$assetModel = AssetModel::where('name', '=', $this->findCsvMatch($row, 'name'))->first();

if ($assetModel) {
if (! $this->updating) {
$this->log('A matching Model '.$this->item['name'].' already exists');
return;
}

$this->log('Updating Model');
$editingAssetModel = true;
} else {
$this->log('No Matching Model, Create a new one');
$assetModel = new AssetModel();
}

// Pull the records from the CSV to determine their values
$this->item['name'] = trim($this->findCsvMatch($row, 'name'));
$this->item['category'] = trim($this->findCsvMatch($row, 'category'));
$this->item['manufacturer'] = trim($this->findCsvMatch($row, 'manufacturer'));
$this->item['min_amt'] = trim($this->findCsvMatch($row, 'min_amt'));
$this->item['model_number'] = trim($this->findCsvMatch($row, 'model_number'));
$this->item['eol'] = trim($this->findCsvMatch($row, 'eol'));
$this->item['notes'] = trim($this->findCsvMatch($row, 'notes'));
$this->item['fieldset'] = trim($this->findCsvMatch($row, 'fieldset'));
$this->item['depreciation'] = trim($this->findCsvMatch($row, 'depreciation'));
$this->item['requestable'] = trim(($this->fetchHumanBoolean($this->findCsvMatch($row, 'requestable'))) == 1) ? 1 : 0;

if (!empty($this->item['category'])) {
if ($category = $this->createOrFetchCategory($this->item['category'])) {
$this->item['category_id'] = $category;
}
}
if (!empty($this->item['manufacturer'])) {
if ($manufacturer = $this->createOrFetchManufacturer($this->item['manufacturer'])) {
$this->item['manufacturer_id'] = $manufacturer;
}
}

if (!empty($this->item['depreciation'])) {
if ($depreciation = $this->fetchDepreciation($this->item['depreciation'])) {
$this->item['depreciation_id'] = $depreciation;
}
}

if (!empty($this->item['fieldset'])) {
if ($fieldset = $this->createOrFetchCustomFieldset($this->item['fieldset'])) {
$this->item['fieldset_id'] = $fieldset;
}
}

Log::debug('Item array is: ');
Log::debug(print_r($this->item, true));


if ($editingAssetModel) {
Log::debug('Updating existing model');
$assetModel->update($this->sanitizeItemForUpdating($assetModel));
} else {
Log::debug('Creating model');
$assetModel->fill($this->sanitizeItemForStoring($assetModel));
$assetModel->created_by = auth()->id();
}

if ($assetModel->save()) {
$this->log('AssetModel '.$assetModel->name.' created or updated from CSV import');
return $assetModel;

} else {
$this->log($assetModel->getErrors()->first());
$this->addErrorToBag($assetModel, $assetModel->getErrors()->keys()[0], $assetModel->getErrors()->first());
return $assetModel->getErrors();
}

}


/**
* Fetch an existing depreciation, or create new if it doesn't exist.
*
* We only do a fetch vs create here since Depreciations have additional fields required
* and cannot be created without them (months, for example.))
*
* @author A. Gianotto
* @since 7.1.3
* @param $depreciation_name string
* @return int id of depreciation created/found
*/
public function fetchDepreciation($depreciation_name) : ?int
{
if ($depreciation_name != '') {

if ($depreciation = Depreciation::where('name', '=', $depreciation_name)->first()) {
$this->log('A matching Depreciation '.$depreciation_name.' already exists');
return $depreciation->id;
}
}

return null;
}

/**
* Fetch an existing fieldset, or create new if it doesn't exist
*
* @author A. Gianotto
* @since 7.1.3
* @param $fieldset_name string
* @return int id of fieldset created/found
*/
public function createOrFetchCustomFieldset($fieldset_name) : ?int
{
if ($fieldset_name != '') {
$fieldset = CustomFieldset::where('name', '=', $fieldset_name)->first();

if ($fieldset) {
$this->log('A matching fieldset '.$fieldset_name.' already exists');
return $fieldset->id;
}

$fieldset = new CustomFieldset();
$fieldset->name = $fieldset_name;

if ($fieldset->save()) {
$this->log('Fieldset '.$fieldset_name.' was created');

return $fieldset->id;
}
$this->logError($fieldset, 'Fieldset');
}

return null;
}
}
3 changes: 2 additions & 1 deletion app/Importer/ComponentImporter.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ public function createComponentIfNotExists()
}
$this->log('No matching component, creating one');
$component = new Component;
$component->created_by = auth()->id();
$component->fill($this->sanitizeItemForStoring($component));

// This sets an attribute on the Loggable trait for the action log
Expand All @@ -58,7 +59,7 @@ public function createComponentIfNotExists()
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,
'created_by' => $this->created_by,
'created_by' => auth()->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,
Expand Down
1 change: 1 addition & 0 deletions app/Importer/ConsumableImporter.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ public function createConsumableIfNotExists($row)
}
$this->log('No matching consumable, creating one');
$consumable = new Consumable();
$consumable->created_by = auth()->id();
$this->item['model_number'] = trim($this->findCsvMatch($row, 'model_number'));
$this->item['item_no'] = trim($this->findCsvMatch($row, 'item_number'));
$this->item['min_amt'] = trim($this->findCsvMatch($row, "min_amt"));
Expand Down
14 changes: 13 additions & 1 deletion app/Importer/Importer.php
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,7 @@ protected function createOrFetchUser($row, $type = 'user')

// No luck finding a user on username or first name, let's create one.
$user = new User;

$user->first_name = $user_array['first_name'];
$user->last_name = $user_array['last_name'];
$user->username = $user_array['username'];
Expand Down Expand Up @@ -406,7 +407,7 @@ protected function findUserByNumber($user_name)
*
* @return self
*/
public function setUserId($created_by)
public function setCreatedBy($created_by)
{
$this->created_by = $created_by;

Expand Down Expand Up @@ -492,6 +493,16 @@ public function setUsernameFormat($usernameFormat)

public function fetchHumanBoolean($value)
{
$true = [
'yes',
'y',
'true',
];

if (in_array(strtolower($value), $true)) {
return 1;
}

return (int) filter_var($value, FILTER_VALIDATE_BOOLEAN);
}

Expand Down Expand Up @@ -528,6 +539,7 @@ public function createOrFetchDepartment($user_department_name)
return null;
}


/**
* Fetch an existing manager
*
Expand Down
Loading

0 comments on commit 3c08760

Please sign in to comment.