8902145288
This should allow us to add custom fields to just about anything we want to within Snipe-IT. Below are the commits that have been squashed together: Initial decoupling of custom field behavior from Assets for re-use Add new DB columns to Custom Fields and fieldsets for 'type' WIP: trying to figure out UI for custom fields for things other than Assets, find problematic places Real progress towards getting to where this stuff might actually work... Fix the table-name determining code for Custom Fields Getting it closer to where Assets at least work Rename the trait to it's new, even better name Solid progress on the new Trait! WIP: HasCustomFields, still working some stuff out Got some basics working; creating custom fields and stuff HasCustomFields now validates and saves Starting to yank the other boilerplate code as things start to work (!) Got the start of defaultValuesForCustomField() working More progress (squash me!) Add migrations for default_values_for_custom_fields table WIP: more towards hasCustomFields trait Progress cleaning up the PR, fixing FIXME's New, passing HasCustomFieldsTrait test! Fix date formatter helper for custom fields Fixed more FIXME's
156 lines
5.8 KiB
PHP
156 lines
5.8 KiB
PHP
<?php
|
|
|
|
namespace App\Importer;
|
|
|
|
use App\Models\Asset;
|
|
use App\Models\Statuslabel;
|
|
|
|
class AssetImporter extends ItemImporter
|
|
{
|
|
protected $defaultStatusLabelId;
|
|
|
|
public function __construct($filename)
|
|
{
|
|
parent::__construct($filename);
|
|
|
|
if (!is_null(Statuslabel::first())) {
|
|
$this->defaultStatusLabelId = Statuslabel::first()->id;
|
|
}
|
|
}
|
|
|
|
protected function handle($row)
|
|
{
|
|
// ItemImporter handles the general fetching.
|
|
parent::handle($row);
|
|
|
|
// FIXME : YUP!!!!! This shit needs to go (?) Yeah?
|
|
if ($this->customFields) {
|
|
foreach ($this->customFields as $customField) {
|
|
$customFieldValue = $this->array_smart_custom_field_fetch($row, $customField); // TODO/FIXME - this might require a new 'mode' on customFill()?
|
|
|
|
if ($customFieldValue) {
|
|
if ($customField->field_encrypted == 1) { // FIXME - repeated code.
|
|
$this->item['custom_fields'][$customField->db_column_name()] = \Crypt::encrypt($customFieldValue);
|
|
$this->log('Custom Field '.$customField->name.': '.\Crypt::encrypt($customFieldValue));
|
|
} else {
|
|
$this->item['custom_fields'][$customField->db_column_name()] = $customFieldValue;
|
|
$this->log('Custom Field '.$customField->name.': '.$customFieldValue);
|
|
}
|
|
} else { // FIXME - think this through? Do we want to blank this? Is that how other stuff works?
|
|
// Clear out previous data.
|
|
$this->item['custom_fields'][$customField->db_column_name()] = null;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
$this->createAssetIfNotExists($row);
|
|
}
|
|
|
|
/**
|
|
* Create the asset if it does not exist.
|
|
*
|
|
* @author Daniel Melzter
|
|
* @since 3.0
|
|
* @param array $row
|
|
* @return Asset|mixed|null
|
|
*/
|
|
public function createAssetIfNotExists(array $row)
|
|
{
|
|
$editingAsset = false;
|
|
$asset_tag = $this->findCsvMatch($row, 'asset_tag');
|
|
|
|
if(empty($asset_tag)){
|
|
$asset_tag = Asset::autoincrement_asset();
|
|
}
|
|
|
|
$asset = Asset::where(['asset_tag'=> (string) $asset_tag])->first();
|
|
if ($asset) {
|
|
if (! $this->updating) {
|
|
$this->log('A matching Asset '.$asset_tag.' already exists');
|
|
|
|
return;
|
|
}
|
|
|
|
$this->log('Updating Asset');
|
|
$editingAsset = true;
|
|
} else {
|
|
$this->log('No Matching Asset, Creating a new one');
|
|
$asset = new Asset;
|
|
}
|
|
$this->item['notes'] = $this->findCsvMatch($row, 'asset_notes');
|
|
$this->item['image'] = $this->findCsvMatch($row, 'image');
|
|
$this->item['requestable'] = ($this->fetchHumanBoolean($this->findCsvMatch($row, 'requestable')) == 1) ? '1' : 0;
|
|
$asset->requestable = $this->item['requestable'];
|
|
$this->item['warranty_months'] = intval($this->findCsvMatch($row, 'warranty_months'));
|
|
$this->item['model_id'] = $this->createOrFetchAssetModel($row);
|
|
$this->item['byod'] = ($this->fetchHumanBoolean($this->findCsvMatch($row, 'byod')) == 1) ? '1' : 0;
|
|
|
|
|
|
// If no status ID is found
|
|
if (! array_key_exists('status_id', $this->item) && ! $editingAsset) {
|
|
$this->log('No status field found, defaulting to first status.');
|
|
$this->item['status_id'] = $this->defaultStatusLabelId;
|
|
}
|
|
|
|
$this->item['asset_tag'] = $asset_tag;
|
|
|
|
// We need to save the user if it exists so that we can checkout to user later.
|
|
// Sanitizing the item will remove it.
|
|
if (array_key_exists('checkout_target', $this->item)) {
|
|
$target = $this->item['checkout_target'];
|
|
}
|
|
$item = $this->sanitizeItemForStoring($asset, $editingAsset);
|
|
// The location id fetched by the csv reader is actually the rtd_location_id.
|
|
// This will also set location_id, but then that will be overridden by the
|
|
// checkout method if necessary below.
|
|
if (isset($this->item['location_id'])) {
|
|
$item['rtd_location_id'] = $this->item['location_id'];
|
|
}
|
|
|
|
$item['last_audit_date'] = null;
|
|
if (isset($this->item['last_audit_date'])) {
|
|
$item['last_audit_date'] = $this->item['last_audit_date'];
|
|
}
|
|
|
|
$item['next_audit_date'] = null;
|
|
if (isset($this->item['next_audit_date'])) {
|
|
$item['next_audit_date'] = $this->item['next_audit_date'];
|
|
}
|
|
|
|
$item['asset_eol_date'] = null;
|
|
if (isset($this->item['asset_eol_date'])) {
|
|
$item['asset_eol_date'] = $this->item['asset_eol_date'];
|
|
}
|
|
|
|
if ($editingAsset) {
|
|
$asset->update($item);
|
|
} else {
|
|
$asset->fill($item);
|
|
}
|
|
|
|
// If we're updating, we don't want to overwrite old fields.
|
|
if (array_key_exists('custom_fields', $this->item)) {
|
|
foreach ($this->item['custom_fields'] as $custom_field => $val) {
|
|
$asset->{$custom_field} = $val;
|
|
}
|
|
}
|
|
|
|
|
|
if ($asset->save()) {
|
|
$asset->logCreate(trans('general.importer.import_note'));
|
|
$this->log('Asset '.$this->item['name'].' with serial number '.$this->item['serial'].' was created');
|
|
|
|
// If we have a target to checkout to, lets do so.
|
|
//-- user_id is a property of the abstract class Importer, which this class inherits from and it's setted by
|
|
//-- the class that needs to use it (command importer or GUI importer inside the project).
|
|
if (isset($target)) {
|
|
$asset->fresh()->checkOut($target, $this->user_id, date('Y-m-d H:i:s'), null, $asset->notes, $asset->name);
|
|
}
|
|
|
|
return;
|
|
}
|
|
$this->logError($asset, 'Asset "'.$this->item['name'].'"');
|
|
}
|
|
}
|