mirror of
https://github.com/snipe/snipe-it.git
synced 2024-11-09 23:24:06 -08:00
Got duplicate-field mapping and minimum-mapping requirements implemented
This commit is contained in:
parent
e1fcfc8dc1
commit
9e573dfa50
|
@ -4,6 +4,7 @@ namespace App\Livewire;
|
|||
|
||||
use App\Models\CustomField;
|
||||
use App\Models\Import;
|
||||
use App\Models\Setting;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Livewire\Attributes\Computed;
|
||||
use Livewire\Component;
|
||||
|
@ -30,6 +31,8 @@ class Importer extends Component
|
|||
public $send_welcome;
|
||||
public $run_backup;
|
||||
public $field_map; // we need a separate variable for the field-mapping, because the keys in the normal array are too complicated for Livewire to understand
|
||||
public $mapping_errors = []; // helps keep track of duplicate mappings
|
||||
public $enough_data_to_import = false;
|
||||
|
||||
// Make these variables public - we set the properties in the constructor so we can localize them (versus the old static arrays)
|
||||
public $accessories_fields;
|
||||
|
@ -107,6 +110,7 @@ class Importer extends Component
|
|||
|
||||
public function updatingTypeOfImport($type)
|
||||
{
|
||||
\Log::error("UPDATING TYPE OF IMPORT!!!!!! to: $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?
|
||||
|
@ -148,6 +152,107 @@ class Importer extends Component
|
|||
}
|
||||
}
|
||||
|
||||
public function updatedFieldMap($value, $index)
|
||||
{
|
||||
\Log::error("Updated (past tense!) THE FIELD MAP! HERE's...something? $index - the value it's changing to is: $value");
|
||||
//check first if you've tried to map two different things to the same field.
|
||||
$already_mapped = [];
|
||||
foreach ($this->field_map as $i => $mapping) {
|
||||
if (!$mapping) {
|
||||
//'Do Not Import' *can* be reused
|
||||
continue;
|
||||
}
|
||||
if (array_key_exists($mapping, $already_mapped)) {
|
||||
$this->mapping_errors[$i] = true;
|
||||
} else {
|
||||
$already_mapped[$mapping] = true;
|
||||
}
|
||||
}
|
||||
|
||||
//finally, check to see if you have enough to import this type of file
|
||||
$this->enough_data_to_import = $this->check_minimum_mappings($already_mapped);
|
||||
}
|
||||
|
||||
private function check_minimum_mappings($already_mapped)
|
||||
{
|
||||
/*****************************
|
||||
* TODO (maybe more than that) -
|
||||
* should we shrink this into some kind of language?
|
||||
* When we allow for an 'update' - should we insist on getting *any* column so we
|
||||
* can guarantee an update?
|
||||
* If we're *not* doing an update, should we have a fuller list?
|
||||
* And, again, is there a better way of doing this other than 'code'? I'm still not sure
|
||||
* (Also, I hate the '@' signs everywhere, it's gross :/)
|
||||
*******************************/
|
||||
switch ($this->typeOfImport) {
|
||||
case 'asset':
|
||||
if ($this->update) {
|
||||
//on *update* you need asset_tag, and something to update
|
||||
return @$already_mapped['asset_tag'] && count($already_mapped) > 1;
|
||||
} else {
|
||||
//model is required on create.
|
||||
if (!@$already_mapped['asset_model']) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//on *create* we need either an asset tag, or we need autoincrement
|
||||
return (Setting::getSetting()->auto_increment_assets || @$already_mapped['asset_tag']);
|
||||
}
|
||||
case 'user':
|
||||
if ($this->update) {
|
||||
//a username + one other field is a valid update.
|
||||
if (@$already_mapped['username'] && count($already_mapped) > 1) {
|
||||
return true;
|
||||
}
|
||||
//or, a full_name and one other field will do
|
||||
if (@$already_mapped['full_name'] && count($already_mapped) > 1) {
|
||||
return true;
|
||||
}
|
||||
//but just a first name isn't enough to update users - you don't have enough to import
|
||||
return false;
|
||||
} else {
|
||||
// to create a new user in the importer, having any *one* of these things is enough to guess
|
||||
// the rest (!)
|
||||
return @$already_mapped['full_name'] || @$already_mapped['username'] || @$already_mapped['first_name'];
|
||||
}
|
||||
case 'accessory':
|
||||
if ($this->update) {
|
||||
return @$already_mapped['name'] && count($already_mapped) > 1;
|
||||
} else {
|
||||
return @$already_mapped['name'] && @$already_mapped['category'] && @$already_mapped['qty'];
|
||||
}
|
||||
case 'consumable':
|
||||
// PHPStorm complains that this 'branch' is a dupe of accessory, and it kinda is,
|
||||
// but it may not *always* be, so let's keep this as its own thing for now
|
||||
if ($this->update) {
|
||||
return @$already_mapped['name'] && count($already_mapped) > 1;
|
||||
} else {
|
||||
return @$already_mapped['name'] && @$already_mapped['category'] && @$already_mapped['qty'];
|
||||
}
|
||||
case 'component':
|
||||
//similarly here for 'component'
|
||||
if ($this->update) {
|
||||
return (@$already_mapped['name'] && count($already_mapped) > 1);
|
||||
} else {
|
||||
return @$already_mapped['name'] && @$already_mapped['category'] && @$already_mapped['qty'];
|
||||
}
|
||||
case 'license':
|
||||
if ($this->update) {
|
||||
return @$already_mapped['name'] && count($already_mapped) > 1;
|
||||
} else {
|
||||
return @$already_mapped['name'] && @$already_mapped['seats'] && @$already_mapped['category'];
|
||||
}
|
||||
case 'location':
|
||||
// Weird - this one is the only one where the update is _stricter_ than the insert!
|
||||
if ($this->update) {
|
||||
return @$already_mapped['name'] && count($already_mapped) > 1;
|
||||
} else {
|
||||
return @$already_mapped['name'];
|
||||
}
|
||||
}
|
||||
return true; //go with a conservative option here, we can tighten this up later
|
||||
|
||||
}
|
||||
public function mount()
|
||||
{
|
||||
$this->authorize('import');
|
||||
|
@ -167,7 +272,7 @@ class Importer extends Component
|
|||
$this->accessories_fields = [
|
||||
'company' => trans('general.company'),
|
||||
'location' => trans('general.location'),
|
||||
'quantity' => trans('general.qty'),
|
||||
'quantity' => trans('general.quantity'),
|
||||
'item_name' => trans('general.item_name_var', ['item' => trans('general.accessory')]),
|
||||
'model_number' => trans('general.model_no'),
|
||||
'notes' => trans('general.notes'),
|
||||
|
@ -229,7 +334,7 @@ class Importer extends Component
|
|||
$this->consumables_fields = [
|
||||
'company' => trans('general.company'),
|
||||
'location' => trans('general.location'),
|
||||
'quantity' => trans('general.qty'),
|
||||
'quantity' => trans('general.quantity'),
|
||||
'item_name' => trans('general.item_name_var', ['item' => trans('general.consumable')]),
|
||||
'model_number' => trans('general.model_no'),
|
||||
'notes' => trans('general.notes'),
|
||||
|
@ -247,7 +352,7 @@ class Importer extends Component
|
|||
$this->components_fields = [
|
||||
'company' => trans('general.company'),
|
||||
'location' => trans('general.location'),
|
||||
'quantity' => trans('general.qty'),
|
||||
'quantity' => trans('general.quantity'),
|
||||
'item_name' => trans('general.item_name_var', ['item' => trans('general.component')]),
|
||||
'model_number' => trans('general.model_no'),
|
||||
'notes' => trans('general.notes'),
|
||||
|
@ -434,7 +539,7 @@ class Importer extends Component
|
|||
'Warranty',
|
||||
'Warranty Months'
|
||||
],
|
||||
'qty' =>
|
||||
'quantity' =>
|
||||
[
|
||||
'QTY',
|
||||
'Quantity'
|
||||
|
@ -493,6 +598,8 @@ class Importer extends Component
|
|||
foreach ($this->importTypes as $type => $name) {
|
||||
$this->columnOptions[$type] = $this->getColumns($type);
|
||||
}
|
||||
|
||||
$this->mapping_errors = [];
|
||||
}
|
||||
|
||||
public function selectFile($id)
|
||||
|
@ -521,6 +628,8 @@ class Importer extends Component
|
|||
}
|
||||
$this->import_errors = null;
|
||||
$this->statusText = null;
|
||||
$this->mapping_errors = [];
|
||||
$this->updatedFieldMap("x", -1); //force trigger the duplicate-fieldmapping (and minimum fieldmapping) code
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -147,7 +147,8 @@
|
|||
{{ trans('general.import_type') }}
|
||||
</label>
|
||||
|
||||
<div class="col-md-9 col-xs-12" wire:ignore>
|
||||
<div class="col-md-9 col-xs-12"
|
||||
wire:ignore> {{-- FIXME - this shouldn't be wire:ignore'd --}}
|
||||
{{ Form::select('typeOfImport', $importTypes, $typeOfImport, [
|
||||
'id' => 'import_type',
|
||||
'class' => 'livewire-select2',
|
||||
|
@ -207,7 +208,7 @@
|
|||
<hr style="border-top: 1px solid lightgray">
|
||||
</div>
|
||||
<div class="form-group col-md-12">
|
||||
<div class="col-md-3 text-right">
|
||||
<div class="col-md-2 text-right">
|
||||
<strong>{{ trans('general.csv_header_field') }}</strong>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
|
@ -216,6 +217,9 @@
|
|||
<div class="col-md-5">
|
||||
<strong>{{ trans('general.sample_value') }}</strong>
|
||||
</div>
|
||||
<div class="col-md-1">
|
||||
<strong>Status</strong> {{-- FIXME - TRANSLATE ME! --}}
|
||||
</div>
|
||||
</div><!-- /div row -->
|
||||
|
||||
@if(! empty($headerRow))
|
||||
|
@ -224,9 +228,9 @@
|
|||
|
||||
<div class="form-group col-md-12" wire:key="header-row-{{ $index }}">
|
||||
|
||||
<label for="field_map.{{ $index }}" class="col-md-3 control-label text-right">{{ $header }}</label>
|
||||
<div class="col-md-4" wire:ignore>
|
||||
|
||||
<label for="field_map.{{ $index }}"
|
||||
class="col-md-2 control-label text-right">{{ $header }}</label>
|
||||
<div class="col-md-4">
|
||||
{{ Form::select('field_map.'.$index, $columnOptions[$typeOfImport], @$field_map[$index],
|
||||
[
|
||||
'class' => 'mappings livewire-select2',
|
||||
|
@ -242,6 +246,11 @@
|
|||
<div class="col-md-5">
|
||||
<p class="form-control-static">{{ str_limit($this->activeFile->first_row[$index], 50, '...') }}</p>
|
||||
</div>
|
||||
<div class="col-md-1">
|
||||
@if(array_key_exists($index, $mapping_errors))
|
||||
BAD MAPPING
|
||||
@endif
|
||||
</div>
|
||||
@else
|
||||
@php
|
||||
$statusText = trans('help.empty_file');
|
||||
|
@ -259,7 +268,9 @@
|
|||
<a href="#" wire:click.prevent="$set('activeFileId',null)">{{ trans('general.cancel') }}</a>
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
<button type="submit" class="btn btn-primary col-md-5" id="import">{{ trans('admin/hardware/message.import.import_button') }}</button>
|
||||
<button type="submit"
|
||||
class="btn btn-primary col-md-5"
|
||||
{{ $enough_data_to_import ? '' : ' disabled="disabled"' }} id="import">{{ trans('admin/hardware/message.import.import_button') }}</button>
|
||||
<br><br>
|
||||
</div>
|
||||
</div>
|
||||
|
|
Loading…
Reference in a new issue