diff --git a/app/Http/Controllers/Api/AssetModelsController.php b/app/Http/Controllers/Api/AssetModelsController.php index e1ae0c12d3..bfcb9d1696 100644 --- a/app/Http/Controllers/Api/AssetModelsController.php +++ b/app/Http/Controllers/Api/AssetModelsController.php @@ -59,6 +59,7 @@ class AssetModelsController extends Controller 'model_number', 'min_amt', 'eol', + 'created_by', 'requestable', 'models.notes', 'models.created_at', @@ -69,7 +70,7 @@ class AssetModelsController extends Controller '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') { @@ -95,7 +96,7 @@ class AssetModelsController extends Controller $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; @@ -105,6 +106,9 @@ class AssetModelsController extends Controller case 'fieldset': $assetmodels->OrderFieldset($order); break; + case 'created_by': + $assetmodels->OrderByCreatedByName($order); + break; default: $assetmodels->orderBy($sort, $order); break; diff --git a/app/Http/Controllers/Api/ImportController.php b/app/Http/Controllers/Api/ImportController.php index 13f4301217..ebf8b550b2 100644 --- a/app/Http/Controllers/Api/ImportController.php +++ b/app/Http/Controllers/Api/ImportController.php @@ -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); } @@ -133,7 +132,7 @@ class ImportController extends Controller } $import->filesize = filesize($path.'/'.$file_name); - + $import->created_by = auth()->id(); $import->save(); $results[] = $import; } @@ -177,6 +176,9 @@ class ImportController extends Controller case 'asset': $redirectTo = 'hardware.index'; break; + case 'assetModel': + $redirectTo = 'models.index'; + break; case 'accessory': $redirectTo = 'accessories.index'; break; diff --git a/app/Http/Requests/ItemImportRequest.php b/app/Http/Requests/ItemImportRequest.php index a6dc0ad7e5..59afdbe09f 100644 --- a/app/Http/Requests/ItemImportRequest.php +++ b/app/Http/Requests/ItemImportRequest.php @@ -38,10 +38,11 @@ class ItemImportRequest extends FormRequest $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 = []; @@ -60,7 +61,7 @@ class ItemImportRequest extends FormRequest $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') diff --git a/app/Http/Transformers/AssetModelsTransformer.php b/app/Http/Transformers/AssetModelsTransformer.php index a7b1c6a49f..dab21d9773 100644 --- a/app/Http/Transformers/AssetModelsTransformer.php +++ b/app/Http/Transformers/AssetModelsTransformer.php @@ -65,6 +65,10 @@ class AssetModelsTransformer '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'), diff --git a/app/Importer/AccessoryImporter.php b/app/Importer/AccessoryImporter.php index eb17c5acad..bc9c1909ff 100644 --- a/app/Importer/AccessoryImporter.php +++ b/app/Importer/AccessoryImporter.php @@ -42,6 +42,7 @@ class AccessoryImporter extends ItemImporter } $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)); diff --git a/app/Importer/AssetModelImporter.php b/app/Importer/AssetModelImporter.php new file mode 100644 index 0000000000..7cfd8a530d --- /dev/null +++ b/app/Importer/AssetModelImporter.php @@ -0,0 +1,174 @@ +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; + } +} \ No newline at end of file diff --git a/app/Importer/ComponentImporter.php b/app/Importer/ComponentImporter.php index 9687ec4f17..3979ba499d 100644 --- a/app/Importer/ComponentImporter.php +++ b/app/Importer/ComponentImporter.php @@ -47,6 +47,7 @@ class ComponentImporter extends ItemImporter } $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 @@ -58,7 +59,7 @@ class ComponentImporter extends ItemImporter 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, diff --git a/app/Importer/ConsumableImporter.php b/app/Importer/ConsumableImporter.php index 9e7019b086..10ffaaedfb 100644 --- a/app/Importer/ConsumableImporter.php +++ b/app/Importer/ConsumableImporter.php @@ -41,6 +41,7 @@ class ConsumableImporter extends ItemImporter } $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")); diff --git a/app/Importer/Importer.php b/app/Importer/Importer.php index 6f2816c7af..907c8b72c5 100644 --- a/app/Importer/Importer.php +++ b/app/Importer/Importer.php @@ -363,6 +363,7 @@ abstract class Importer // 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']; @@ -406,7 +407,7 @@ abstract class Importer * * @return self */ - public function setUserId($created_by) + public function setCreatedBy($created_by) { $this->created_by = $created_by; @@ -492,6 +493,16 @@ abstract class Importer public function fetchHumanBoolean($value) { + $true = [ + 'yes', + 'y', + 'true', + ]; + + if (in_array(strtolower($value), $true)) { + return 1; + } + return (int) filter_var($value, FILTER_VALIDATE_BOOLEAN); } @@ -528,6 +539,7 @@ abstract class Importer return null; } + /** * Fetch an existing manager * diff --git a/app/Importer/ItemImporter.php b/app/Importer/ItemImporter.php index 360618f4f0..6b1d647136 100644 --- a/app/Importer/ItemImporter.php +++ b/app/Importer/ItemImporter.php @@ -94,7 +94,7 @@ class ItemImporter extends Importer $this->item['qty'] = $this->findCsvMatch($row, 'quantity'); $this->item['requestable'] = $this->findCsvMatch($row, 'requestable'); - $this->item['created_by'] = $this->created_by; + $this->item['created_by'] = auth()->id(); $this->item['serial'] = $this->findCsvMatch($row, 'serial'); // NO need to call this method if we're running the user import. // TODO: Merge these methods. @@ -113,7 +113,7 @@ class ItemImporter extends Importer protected function determineCheckout($row) { // Locations don't get checked out to anyone/anything - if (get_class($this) == LocationImporter::class) { + if ((get_class($this) == LocationImporter::class) || (get_class($this) == AssetModelImporter::class)) { return; } @@ -249,6 +249,7 @@ class ItemImporter extends Importer $this->log('No Matching Model, Creating a new one'); $asset_model = new AssetModel(); + $asset_model->created_by = auth()->id(); $item = $this->sanitizeItemForStoring($asset_model, $editingModel); $item['name'] = $asset_model_name; $item['model_number'] = $asset_modelNumber; @@ -256,11 +257,8 @@ class ItemImporter extends Importer $item['category_id'] = $this->createOrFetchCategory($asset_model_category); $asset_model->fill($item); - //$asset_model = AssetModel::firstOrNew($item); $item = null; - - if ($asset_model->save()) { $this->log('Asset Model '.$asset_model_name.' with model number '.$asset_modelNumber.' was created'); @@ -287,21 +285,28 @@ class ItemImporter extends Importer $classname = class_basename(get_class($this)); $item_type = strtolower(substr($classname, 0, strpos($classname, 'Importer'))); + // If we're importing asset models only (without attached assets), override the category type to asset + if ($item_type == 'assetmodel') { + $item_type = 'asset'; + } + if (empty($asset_category)) { $asset_category = 'Unnamed Category'; } + + $category = Category::where(['name' => $asset_category, 'category_type' => $item_type])->first(); - if ($category) { - $this->log('A matching category: '.$asset_category.' already exists'); + if ($category) { + $this->log('A matching category: '.$category->name.' already exists'); return $category->id; } $category = new Category(); + $category->created_by = auth()->id(); $category->name = $asset_category; $category->category_type = $item_type; - $category->created_by = $this->created_by; if ($category->save()) { $this->log('Category '.$asset_category.' was created'); @@ -330,6 +335,7 @@ class ItemImporter extends Importer return $company->id; } $company = new Company(); + $company->created_by = auth()->id(); $company->name = $asset_company_name; if ($company->save()) { @@ -386,6 +392,7 @@ class ItemImporter extends Importer } $this->log('Creating a new status'); $status = new Statuslabel(); + $status->created_by = auth()->id(); $status->name = trim($asset_statuslabel_name); $status->deployable = 1; @@ -425,7 +432,7 @@ class ItemImporter extends Importer //Otherwise create a manufacturer. $manufacturer = new Manufacturer(); $manufacturer->name = trim($item_manufacturer); - $manufacturer->created_by = $this->created_by; + $manufacturer->created_by = auth()->id(); if ($manufacturer->save()) { $this->log('Manufacturer '.$manufacturer->name.' was created'); @@ -466,7 +473,7 @@ class ItemImporter extends Importer $location->city = ''; $location->state = ''; $location->country = ''; - $location->created_by = $this->created_by; + $location->created_by = auth()->id(); if ($location->save()) { $this->log('Location '.$asset_location.' was created'); @@ -502,7 +509,7 @@ class ItemImporter extends Importer $supplier = new Supplier(); $supplier->name = $item_supplier; - $supplier->created_by = $this->created_by; + $supplier->created_by = auth()->id(); if ($supplier->save()) { $this->log('Supplier '.$item_supplier.' was created'); diff --git a/app/Importer/LicenseImporter.php b/app/Importer/LicenseImporter.php index 3f7bb9f85c..0dc7475478 100644 --- a/app/Importer/LicenseImporter.php +++ b/app/Importer/LicenseImporter.php @@ -84,6 +84,7 @@ class LicenseImporter extends ItemImporter $license->update($this->sanitizeItemForUpdating($license)); } else { $license->fill($this->sanitizeItemForStoring($license)); + $license->created_by = auth()->id(); } // This sets an attribute on the Loggable trait for the action log diff --git a/app/Importer/LocationImporter.php b/app/Importer/LocationImporter.php index b3ef59d248..a9a5152234 100644 --- a/app/Importer/LocationImporter.php +++ b/app/Importer/LocationImporter.php @@ -51,6 +51,7 @@ class LocationImporter extends ItemImporter } else { $this->log('No Matching Location, Create a new one'); $location = new Location; + $location->created_by = auth()->id(); } // Pull the records from the CSV to determine their values @@ -65,7 +66,6 @@ class LocationImporter extends ItemImporter $this->item['ldap_ou'] = trim($this->findCsvMatch($row, 'ldap_ou')); $this->item['manager'] = trim($this->findCsvMatch($row, 'manager')); $this->item['manager_username'] = trim($this->findCsvMatch($row, 'manager_username')); - $this->item['created_by'] = auth()->id(); if ($this->findCsvMatch($row, 'parent_location')) { $this->item['parent_id'] = $this->createOrFetchLocation(trim($this->findCsvMatch($row, 'parent_location'))); diff --git a/app/Importer/UserImporter.php b/app/Importer/UserImporter.php index 036bf15c9a..77317b3d09 100644 --- a/app/Importer/UserImporter.php +++ b/app/Importer/UserImporter.php @@ -114,6 +114,7 @@ class UserImporter extends ItemImporter $this->log('No matching user, creating one'); $user = new User(); + $user->created_by = auth()->id(); $user->fill($this->sanitizeItemForStoring($user)); if ($user->save()) { diff --git a/app/Livewire/Importer.php b/app/Livewire/Importer.php index bffb3d763c..75b707b8ad 100644 --- a/app/Livewire/Importer.php +++ b/app/Livewire/Importer.php @@ -73,6 +73,9 @@ class Importer extends Component case 'asset': $results = $this->assets_fields; break; + case 'assetModel': + $results = $this->assetmodels_fields; + break; case 'accessory': $results = $this->accessories_fields; break; @@ -82,6 +85,9 @@ class Importer extends Component case 'component': $results = $this->components_fields; break; + case 'consumable': + $results = $this->consumables_fields; + break; case 'license': $results = $this->licenses_fields; break; @@ -91,10 +97,14 @@ class Importer extends Component case 'location': $results = $this->locations_fields; break; + case 'user': + $results = $this->users_fields; + break; default: $results = []; } asort($results, SORT_FLAG_CASE | SORT_STRING); + if ($type == "asset") { // add Custom Fields after a horizontal line $results['-'] = "———" . trans('admin/custom_fields/general.custom_fields') . "———’"; @@ -107,6 +117,7 @@ class Importer extends Component public function updatingTypeOfImport($type) { + // go through each header, find a matching field to try and map it to. foreach ($this->headerRow as $i => $header) { // do we have something mapped already? @@ -152,13 +163,14 @@ class Importer extends Component { $this->authorize('import'); $this->importTypes = [ - 'asset' => trans('general.assets'), - 'accessory' => trans('general.accessories'), - 'consumable' => trans('general.consumables'), - 'component' => trans('general.components'), - 'license' => trans('general.licenses'), - 'user' => trans('general.users'), - 'location' => trans('general.locations'), + 'accessory' => trans('general.accessories'), + 'asset' => trans('general.assets'), + 'assetModel' => trans('general.asset_models'), + 'component' => trans('general.components'), + 'consumable' => trans('general.consumables'), + 'license' => trans('general.licenses'), + 'location' => trans('general.locations'), + 'user' => trans('general.users'), ]; /** @@ -331,6 +343,19 @@ class Importer extends Component 'parent_location' => trans('admin/locations/table.parent'), ]; + $this->assetmodels_fields = [ + 'item_name' => trans('general.item_name_var', ['item' => trans('general.asset_model')]), + 'category' => trans('general.category'), + 'manufacturer' => trans('general.manufacturer'), + 'model_number' => trans('general.model_no'), + 'notes' => trans('general.item_notes', ['item' => trans('admin/hardware/form.model')]), + 'min_amt' => trans('mail.min_QTY'), + 'fieldset' => trans('admin/models/general.fieldset'), + 'eol' => trans('general.eol'), + 'requestable' => trans('admin/models/general.requestable'), + + ]; + // "real fieldnames" to a list of aliases for that field $this->aliases_fields = [ 'item_name' => @@ -359,6 +384,23 @@ class Importer extends Component 'eol date', 'asset eol date', ], + 'eol' => + [ + 'eol', + 'EOL', + 'eol months', + ], + 'depreciation' => + [ + 'Depreciation', + 'depreciation', + ], + 'requestable' => + [ + 'requestable', + 'Requestable', + ], + 'gravatar' => [ 'gravatar', @@ -503,7 +545,6 @@ class Importer extends Component if (!$this->activeFile) { $this->message = trans('admin/hardware/message.import.file_missing'); $this->message_type = 'danger'; - return; } @@ -518,6 +559,8 @@ class Importer extends Component $this->field_map[] = null; // re-inject the 'nulls' if a file was imported with some 'Do Not Import' settings } } + + $this->file_id = $id; $this->import_errors = null; $this->statusText = null; diff --git a/app/Livewire/SlackSettingsForm.php b/app/Livewire/SlackSettingsForm.php index 725bffa249..8d330bafbe 100644 --- a/app/Livewire/SlackSettingsForm.php +++ b/app/Livewire/SlackSettingsForm.php @@ -113,7 +113,9 @@ class SlackSettingsForm extends Component if($this->webhook_selected == 'microsoft' || $this->webhook_selected == 'google'){ $this->webhook_channel = '#NA'; } - + } + public function updatedwebhookEndpoint() { + $this->teams_webhook_deprecated = !Str::contains($this->webhook_endpoint, 'workflows'); } public function updatedwebhookEndpoint() { $this->teams_webhook_deprecated = !Str::contains($this->webhook_endpoint, 'workflows'); diff --git a/app/Models/AssetModel.php b/app/Models/AssetModel.php index 0c8f8e7b3c..02b5df40d1 100755 --- a/app/Models/AssetModel.php +++ b/app/Models/AssetModel.php @@ -68,6 +68,7 @@ class AssetModel extends SnipeModel 'model_number', 'name', 'notes', + 'requestable', ]; use Searchable; @@ -328,4 +329,14 @@ class AssetModel extends SnipeModel { return $query->leftJoin('custom_fieldsets', 'models.fieldset_id', '=', 'custom_fieldsets.id')->orderBy('custom_fieldsets.name', $order); } + + /** + * Query builder scope to order on created_by name + * + */ + public function scopeOrderByCreatedByName($query, $order) + { + return $query->leftJoin('users as admin_sort', 'models.created_by', '=', 'admin_sort.id')->select('models.*')->orderBy('admin_sort.first_name', $order)->orderBy('admin_sort.last_name', $order); + } + } diff --git a/app/Models/Import.php b/app/Models/Import.php index 052612a197..d824a3840c 100644 --- a/app/Models/Import.php +++ b/app/Models/Import.php @@ -14,4 +14,16 @@ class Import extends Model 'first_row' => 'array', 'field_map' => 'json', ]; + + /** + * Establishes the license -> admin user relationship + * + * @author A. Gianotto + * @since [v2.0] + * @return \Illuminate\Database\Eloquent\Relations\Relation + */ + public function adminuser() + { + return $this->belongsTo(\App\Models\User::class, 'created_by'); + } } diff --git a/database/factories/ImportFactory.php b/database/factories/ImportFactory.php index 0b0f79aa44..11fdbe17a9 100644 --- a/database/factories/ImportFactory.php +++ b/database/factories/ImportFactory.php @@ -143,4 +143,26 @@ class ImportFactory extends Factory return $attributes; }); } + + + + /** + * Create an asset model import type. + * + * @return static + */ + public function assetmodel() + { + return $this->state(function (array $attributes) { + $fileBuilder = Importing\AssetModelsImportFileBuilder::new(); + + $attributes['name'] = "{$attributes['name']} Asset Model"; + $attributes['import_type'] = 'assetModel'; + $attributes['header_row'] = $fileBuilder->toCsv()[0]; + $attributes['first_row'] = $fileBuilder->firstRow(); + + return $attributes; + }); + } + } diff --git a/resources/lang/en-US/general.php b/resources/lang/en-US/general.php index a2a075eed0..05e4c8e4c4 100644 --- a/resources/lang/en-US/general.php +++ b/resources/lang/en-US/general.php @@ -560,7 +560,7 @@ return [ 'something_went_wrong' => 'Something went wrong with your request.', 'close' => 'Close', 'expires' => 'Expires', - 'map_fields'=> 'Map :item_type Field', + 'map_fields'=> 'Map :item_type Fields', 'remaining_var' => ':count Remaining', 'label' => 'Label', 'import_asset_tag_exists' => 'An asset with the asset tag :asset_tag already exists and an update was not requested. No change was made.', diff --git a/resources/views/livewire/importer.blade.php b/resources/views/livewire/importer.blade.php index e69a38b187..027d9e3dc6 100644 --- a/resources/views/livewire/importer.blade.php +++ b/resources/views/livewire/importer.blade.php @@ -105,13 +105,17 @@ class="col-md-12 table table-striped snipe-table"> - + {{ trans('general.file_name') }} - + {{ trans('general.created_at') }} - + + {{ trans('general.created_by') }} + + + {{ trans('general.filesize') }} @@ -122,9 +126,10 @@ @foreach($this->files as $currentFile) - {{ $currentFile->file_path }} - {{ Helper::getFormattedDateObject($currentFile->created_at, 'datetime', false) }} - {{ Helper::formatFilesizeUnits($currentFile->filesize) }} + {{ $currentFile->file_path }} + {{ Helper::getFormattedDateObject($currentFile->created_at, 'datetime', false) }} + {{ ($currentFile->adminuser) ? $currentFile->adminuser->present()->fullName : '--'}} + {{ Helper::formatFilesizeUnits($currentFile->filesize) }}