mirror of
https://github.com/snipe/snipe-it.git
synced 2025-03-05 20:52:15 -08:00
Add improved field-guessing logic; make sure 'do not map' fields work
This commit is contained in:
parent
7edec26e73
commit
fe699737eb
|
@ -31,7 +31,7 @@ class ImporterFile extends Component
|
|||
public function generate_field_map()
|
||||
{
|
||||
$tmp = array_combine($this->activeFile->header_row, $this->field_map);
|
||||
return json_encode($tmp);
|
||||
return json_encode(array_filter($tmp));
|
||||
}
|
||||
|
||||
static $general = [
|
||||
|
@ -102,16 +102,17 @@ class ImporterFile extends Component
|
|||
'country' => 'Country',
|
||||
];
|
||||
|
||||
//array of "real fieldnames" to a list of aliases for that field
|
||||
static $aliases = [
|
||||
'model_number' => ['model', 'model no','model no.','model number', 'model num', 'model num.'],
|
||||
'warranty_months' => ['Warranty', 'Warranty Months']
|
||||
];
|
||||
|
||||
private function getColumns($type)
|
||||
{
|
||||
$customFields = [];
|
||||
foreach($this->customFields AS $field) {
|
||||
$customFields[$field->db_column_name()] = $field->name;
|
||||
}
|
||||
|
||||
switch($type) {
|
||||
case 'asset':
|
||||
$results = self::$general + self::$assets + $customFields;
|
||||
$results = self::$general + self::$assets;
|
||||
break;
|
||||
case 'accessory':
|
||||
$results = self::$general + self::$accessories;
|
||||
|
@ -129,13 +130,59 @@ class ImporterFile extends Component
|
|||
$results = self::$general;
|
||||
}
|
||||
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')."———’";
|
||||
foreach(CustomField::orderBy('name')->get() AS $field) {
|
||||
$results[$field->db_column_name()] = $field->name;
|
||||
}
|
||||
}
|
||||
return $results;
|
||||
}
|
||||
|
||||
public function updating($name, $new_import_type)
|
||||
{
|
||||
if ($name == "activeFile.import_type") {
|
||||
\Log::info("WE ARE CHANGING THE import_type!!!!! TO: ".$new_import_type);
|
||||
// go through each header, find a matching field to try and map it to.
|
||||
foreach($this->activeFile->header_row as $i => $header) {
|
||||
// do we have something mapped already?
|
||||
if (array_key_exists($i, $this->field_map)) {
|
||||
// yes, we do. Is it valid for this type of import?
|
||||
// (e.g. the import type might have been changed...?)
|
||||
if (array_key_exists($this->field_map[$i], $this->columnOptions[$value])) {
|
||||
//yes, this key *is* valid. Continue on to the next field.
|
||||
continue;
|
||||
} else {
|
||||
//no, this key is *INVALID* for this import type. Better set it to null
|
||||
// and we'll hope that the aliases or something else picks it up.
|
||||
$this->field_map[$i] = null; // fingers crossed! But it's not likely, tbh.
|
||||
} // TODO - strictly speaking, this isn't necessary here I don't think.
|
||||
}
|
||||
// first, check for exact matches
|
||||
foreach ($this->columnOptions[$new_import_type] AS $value => $text) {
|
||||
if (strcasecmp($text, $header) === 0) { // case-INSENSITIVe on purpose!
|
||||
$this->field_map[$i] = $value;
|
||||
continue 2; //don't bother with the alias check, go to the next header
|
||||
}
|
||||
}
|
||||
// if you got here, we didn't find a match. Try the aliases
|
||||
foreach(self::$aliases as $key => $alias_values) {
|
||||
foreach($alias_values as $alias_value) {
|
||||
if (strcasecmp($alias_value,$header) === 0) { // aLsO CaSe-INSENSitiVE!
|
||||
$this->field_map[$i] = $key;
|
||||
continue 3; // bust out of both of these loops; as well as the surrounding one - e.g. move on to the next header
|
||||
}
|
||||
}
|
||||
}
|
||||
// and if you got here, we got nothing. Let's recommend 'null'
|
||||
$this->field_map[$i] = null; // Booooo :(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function mount()
|
||||
{
|
||||
$this->customFields = CustomField::all();
|
||||
|
||||
$this->importTypes = [
|
||||
'asset' => 'Assets', // TODO - translate!
|
||||
'accessory' => 'Accessories',
|
||||
|
@ -149,7 +196,6 @@ class ImporterFile extends Component
|
|||
foreach($this->importTypes AS $type => $name) {
|
||||
$this->columnOptions[$type] = $this->getColumns($type);
|
||||
}
|
||||
$this->increment = 0;
|
||||
$this->field_map = $this->activeFile->field_map ? array_values($this->activeFile->field_map): [];
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<tr>
|
||||
<tr id="importer-file">
|
||||
<td colspan="5">
|
||||
<div class="col-md-12">
|
||||
|
||||
|
@ -9,7 +9,13 @@
|
|||
</div>
|
||||
|
||||
<div class="col-md-7 col-xs-12">
|
||||
{{ Form::select('activeFile.import_type', $importTypes, $activeFile->import_type, ['id' => 'import_type', 'class' => 'livewire-select2', 'style' => 'min-width: 350px', 'data-placeholder' => 'Select an import type...', /* TODO: translate me */ 'placeholder' => '', 'data-livewire-component' => $_instance->id]) }}
|
||||
{{ Form::select('activeFile.import_type', $importTypes, $activeFile->import_type, [
|
||||
'id' => 'import_type',
|
||||
'class' => 'livewire-select2',
|
||||
'style' => 'min-width: 350px',
|
||||
'data-placeholder' => 'Select an import type...', /* TODO: translate me */
|
||||
'data-livewire-component' => $_instance->id
|
||||
]) }}
|
||||
</div>
|
||||
|
||||
</div><!-- /dynamic-form-row -->
|
||||
|
@ -70,8 +76,9 @@
|
|||
'class' => 'mappings livewire-select2',
|
||||
'placeholder' => 'Do Not Import',
|
||||
'data-livewire-component' => $_instance->id
|
||||
],[
|
||||
'-' => ['disabled' => true] // this makes the "-----" line unclickable
|
||||
])
|
||||
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -113,52 +120,57 @@ $(function () {
|
|||
$('.minimal.livewire-icheck').iCheck({
|
||||
checkboxClass: 'icheckbox_minimal-blue',
|
||||
})
|
||||
})
|
||||
$('#import').on('click', function () {
|
||||
if(!@this.activeFile.import_type) {
|
||||
@this.statusType='error';
|
||||
@this.statusText= "An import type is required... "; //TODO: translate?
|
||||
return;
|
||||
}
|
||||
@this.statusType='pending';
|
||||
@this.statusText = "Processing...";
|
||||
@this.generate_field_map().then(function (mappings_raw) {
|
||||
var mappings = JSON.parse(mappings_raw)
|
||||
console.warn("Here is the mappings:")
|
||||
console.dir(mappings)
|
||||
$.post({
|
||||
url: "{{ route('api.imports.importFile', $activeFile->id) }}",
|
||||
data: {
|
||||
'import-update': !!@this.update,
|
||||
'send-welcome': !!@this.send_welcome,
|
||||
'import-type': @this.activeFile.import_type,
|
||||
'run-backup': !!@this.run_backup,
|
||||
'column-mappings': mappings
|
||||
},
|
||||
headers: {
|
||||
"X-CSRF-TOKEN": $('meta[name="csrf-token"]').attr('content')
|
||||
}
|
||||
}).done( function (body) {
|
||||
// Success
|
||||
@this.statusType="success";
|
||||
@this.statusText = "Success... Redirecting.";
|
||||
console.dir(body)
|
||||
window.location.href = body.messages.redirect_url;
|
||||
}).fail( function (jqXHR, textStatus, error) {
|
||||
// Failure
|
||||
var body = jqXHR.responseJSON
|
||||
if(body.status == 'import-errors') {
|
||||
@this.emit('importError', body.messages);
|
||||
@this.statusType='error';
|
||||
@this.statusText = "Error";
|
||||
} else {
|
||||
console.warn("Not import-errors, just regular errors")
|
||||
|
||||
// we have to hook up to the `<tr id='importer-file'>` at the root of this display,
|
||||
// because the #import button isn't visible until you click an import_type
|
||||
$('#importer-file').on('click', '#import', function () {
|
||||
console.warn("You clicked it!!!!")
|
||||
if(!@this.activeFile.import_type) {
|
||||
@this.statusType='error';
|
||||
@this.statusText= "An import type is required... "; //TODO: translate?
|
||||
return;
|
||||
}
|
||||
@this.statusType='pending';
|
||||
@this.statusText = "Processing...";
|
||||
@this.generate_field_map().then(function (mappings_raw) {
|
||||
var mappings = JSON.parse(mappings_raw)
|
||||
// console.warn("Here is the mappings:")
|
||||
// console.dir(mappings)
|
||||
$.post({
|
||||
url: "{{ route('api.imports.importFile', $activeFile->id) }}",
|
||||
contentType: 'application/json',
|
||||
data: JSON.stringify({
|
||||
'import-update': !!@this.update,
|
||||
'send-welcome': !!@this.send_welcome,
|
||||
'import-type': @this.activeFile.import_type,
|
||||
'run-backup': !!@this.run_backup,
|
||||
'column-mappings': mappings
|
||||
}),
|
||||
headers: {
|
||||
"X-CSRF-TOKEN": $('meta[name="csrf-token"]').attr('content')
|
||||
}
|
||||
}).done( function (body) {
|
||||
// Success
|
||||
@this.statusType="success";
|
||||
@this.statusText = "Success... Redirecting.";
|
||||
console.dir(body)
|
||||
@this.emit('alert', body.error)
|
||||
}
|
||||
@this.emit('hideDetails')
|
||||
});
|
||||
})
|
||||
return false;
|
||||
});
|
||||
window.location.href = body.messages.redirect_url;
|
||||
}).fail( function (jqXHR, textStatus, error) {
|
||||
// Failure
|
||||
var body = jqXHR.responseJSON
|
||||
if(body.status == 'import-errors') {
|
||||
@this.emit('importError', body.messages);
|
||||
@this.statusType='error';
|
||||
@this.statusText = "Error";
|
||||
} else {
|
||||
console.warn("Not import-errors, just regular errors")
|
||||
console.dir(body)
|
||||
@this.emit('alert', body.error)
|
||||
}
|
||||
@this.emit('hideDetails')
|
||||
});
|
||||
})
|
||||
return false;
|
||||
});})
|
||||
|
||||
</script>
|
|
@ -36,7 +36,7 @@
|
|||
<tbody>
|
||||
@foreach($import_errors as $field => $error_list)
|
||||
<tr>
|
||||
<td>{{ $processDetails->file_path }}</td>
|
||||
<td>{{ $processDetails->file_path ?? "Unknown File" }}</td>
|
||||
<td>
|
||||
<b>{{ $field }}:</b>
|
||||
<span>{{ implode(", ",$error_list) }}</span>
|
||||
|
|
Loading…
Reference in a new issue