Port import manager code to develop

This commit is contained in:
snipe 2018-10-03 00:52:29 -07:00
parent 8937edb97e
commit c8ad45b11e
14 changed files with 177 additions and 87 deletions

View file

@ -74,6 +74,7 @@ class ObjectImportCommand extends Command
$importer->setCallbacks([$this, 'log'], [$this, 'progress'], [$this, 'errorCallback'])
->setUserId($this->option('user_id'))
->setUpdating($this->option('update'))
->setShouldNotify($this->option('send-welcome'))
->setUsernameFormat($this->option('username_format'));
$logFile = $this->option('logfile');

View file

@ -50,6 +50,7 @@ class ItemImportRequest extends FormRequest
$importer->setCallbacks([$this, 'log'], [$this, 'progress'], [$this, 'errorCallback'])
->setUserId(Auth::id())
->setUpdating($this->has('import-update'))
->setShouldNotify($this->has('send-welcome'))
->setUsernameFormat('firstname.lastname')
->setFieldMappings($fieldMappings);
// $logFile = storage_path('logs/importer.log');

View file

@ -66,7 +66,9 @@ abstract class Importer
'phone_number' => 'phone number',
'first_name' => 'first name',
'last_name' => 'last name',
'department' => 'department'
'department' => 'department',
'manager_first_name' => 'manager last name',
'manager_last_name' => 'manager last name',
];
/**
* Map of item fields->csv names
@ -207,7 +209,6 @@ abstract class Importer
public function lookupCustomKey($key)
{
if (array_key_exists($key, $this->fieldMap)) {
// $this->log("Found a match in our custom map: {$key} is " . $this->fieldMap[$key]);
return $this->fieldMap[$key];
}
// Otherwise no custom key, return original.
@ -323,6 +324,8 @@ abstract class Importer
$user->last_name = $user_array['last_name'];
$user->username = $user_array['username'];
$user->email = $user_array['email'];
$user->manager_id = $user_array['manager_id'];
$user->department_id = $user_array['department_id'];
$user->activated = 1;
$user->password = $this->tempPassword;
@ -376,6 +379,20 @@ abstract class Importer
return $this;
}
/**
* Sets whether or not we should notify the user with a welcome email
*
* @param bool $send_welcome the send-welcome flag
*
* @return self
*/
public function setShouldNotify($send_welcome)
{
$this->send_welcome = $send_welcome;
return $this;
}
/**
* Defines mappings of csv fields
*

View file

@ -10,6 +10,7 @@ use App\Models\Location;
use App\Models\Manufacturer;
use App\Models\Statuslabel;
use App\Models\Supplier;
use App\Models\Department;
use App\Models\User;
class ItemImporter extends Importer
@ -54,6 +55,19 @@ class ItemImporter extends Importer
if ($this->shouldUpdateField($item_supplier)) {
$this->item['supplier_id'] = $this->createOrFetchSupplier($item_supplier);
}
$item_department = $this->findCsvMatch($row, "department");
if ($this->shouldUpdateField($item_department)) {
$this->item['department_id'] = $this->createOrFetchDepartment($item_department);
}
$item_manager_first_name = $this->findCsvMatch($row, "manage_first_name");
$item_manager_last_name = $this->findCsvMatch($row, "manage_last_name");
if ($this->shouldUpdateField($item_manager_first_name)) {
$this->item['manager_id'] = $this->fetchManager($item_manager_first_name, $item_manager_last_name);
}
$this->item["name"] = $this->findCsvMatch($row, "item_name");
$this->item["notes"] = $this->findCsvMatch($row, "notes");
$this->item["order_number"] = $this->findCsvMatch($row, "order_number");
@ -84,7 +98,7 @@ class ItemImporter extends Importer
*/
protected function determineCheckout($row)
{
// We only support checkout-to-location for asset, so short circuit otherw.
// We only support checkout-to-location for asset, so short circuit otherwise.
if(get_class($this) != AssetImporter::class) {
return $this->createOrFetchUser($row);
}
@ -160,8 +174,7 @@ class ItemImporter extends Importer
* @author Daniel Melzter
* @since 3.0
* @param array
* @param $category Category
* @param $manufacturer Manufacturer
* @param $row Row
* @return int Id of asset model created/found
* @internal param $asset_modelno string
*/
@ -279,6 +292,27 @@ class ItemImporter extends Importer
return null;
}
/**
* Fetch an existing manager
*
* @author A. Gianotto
* @since 4.6.5
* @param $user_manager string
* @return int id of company created/found
*/
public function fetchManager($user_manager_first_name, $user_manager_last_name)
{
$manager = User::where('first_name', '=', $user_manager_first_name)
->where('last_name', '=', $user_manager_last_name)->first();
if ($manager) {
$this->log('A matching Manager ' . $user_manager_first_name . ' '. $user_manager_last_name . ' already exists');
return $manager->id;
}
$this->log('No matching Manager ' . $user_manager_first_name . ' '. $user_manager_last_name . ' found. If their user account is being created through this import, you should re-process this file again. ');
return null;
}
/**
* Fetch the existing status label or create new if it doesn't exist.
*

View file

@ -13,7 +13,6 @@ class UserImporter extends ItemImporter
public function __construct($filename)
{
parent::__construct($filename);
// $this->users = User::all();
}
protected function handle($row)
@ -39,7 +38,11 @@ class UserImporter extends ItemImporter
$this->item['email'] = $this->findCsvMatch($row, 'email');
$this->item['phone'] = $this->findCsvMatch($row, 'phone_number');
$this->item['jobtitle'] = $this->findCsvMatch($row, 'jobtitle');
$this->item['activated'] = $this->findCsvMatch($row, 'activated');
$this->item['employee_num'] = $this->findCsvMatch($row, 'employee_num');
$this->item['department_id'] = $this->createOrFetchDepartment($this->findCsvMatch($row, 'department'));
$this->item['manager_id'] = $this->fetchManager($this->findCsvMatch($row, 'manager_first_name'), $this->findCsvMatch($row, 'manager_last_name'));
$user_department = $this->findCsvMatch($row, 'department');
if ($this->shouldUpdateField($user_department)) {
$this->item["department_id"] = $this->createOrFetchDepartment($user_department);
@ -73,8 +76,10 @@ class UserImporter extends ItemImporter
'last_name' => $user->last_name,
'password' => $this->tempPassword,
];
if ($this->send_welcome) {
$user->notify(new WelcomeNotification($data));
}
}
$user = null;
$this->item = null;
return;

View file

@ -1,16 +1,19 @@
| CSV | Item | Applicable Types |
|---------------------|------------------|-------------------------------------------|
| activated | | User |
| asset tag | asset_tag | Asset |
| category | category | All |
| company | company | All |
| item name | item_name | All |
| image | image | asset |
| image | image | Asset |
| department_id | | User ? All |
| expiration date | expiration_date | License |
| location | location | All |
| notes | notes | All |
| licensed to email | license_email | License |
| licensed to name | license_name | License |
| maintained | maintained | License |
| manager_id | | User |
| manufacturer | manufacturer | All |
| model name | asset_model | Asset |
| model number | model_number | Asset |
@ -22,11 +25,11 @@
| reassignable | reassignable | License |
| requestable | requestable | Asset, Accessory? |
| seats | seats | License |
| serial number | serial | asset, license |
| status | status | asset ? All |
| serial number | serial | Asset, license |
| status | status | Asset ? All |
| supplier | supplier | Asset ? All |
| termination date | termination_date | License |
| warranty months | warranty_months | asset |
| warranty months | warranty_months | Asset |
| User Related Fields | assigned_to | Asset |
| name | | |
| email | | |

View file

@ -26,7 +26,7 @@ class Department extends SnipeModel
protected $rules = [
'name' => 'required|max:255',
'user_id' => 'required',
'user_id' => 'nullable|exists:users,id',
'location_id' => 'numeric|nullable',
'company_id' => 'numeric|nullable',
'manager_id' => 'numeric|nullable',

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
public/js/dist/all.js vendored

Binary file not shown.

Binary file not shown.

View file

@ -1,8 +1,8 @@
{
"/js/build/vue.js": "/js/build/vue.js?id=8a5d892d5cd2d6195c15",
"/js/build/vue.js": "/js/build/vue.js?id=385b35bd13d097237275",
"/css/build/AdminLTE.css": "/css/build/AdminLTE.css?id=5002486f605469c322ed",
"/css/build/app.css": "/css/build/app.css?id=0c4d55f9abe9a4efe526",
"/js/build/vue.js.map": "/js/build/vue.js.map?id=770b634768b61b2b8104",
"/js/build/vue.js.map": "/js/build/vue.js.map?id=d694e63456d4ed2ba993",
"/css/build/AdminLTE.css.map": "/css/build/AdminLTE.css.map?id=fa40c591a5b361cb0761",
"/css/build/app.css.map": "/css/build/app.css.map?id=5a1bc8c3be0d3da37d0a",
"/css/all.css": "/css/all.css?id=2d7f3b6654a518d7e0c5",
@ -13,9 +13,9 @@
"/css/signature-pad.min.css": "/css/signature-pad.min.css?id=6a89d3cd901305e66ced",
"/css/blue.png": "/css/blue.png?id=4c85d6a97173123bd14a",
"/css/blue@2x.png": "/css/blue@2x.png?id=62c67c6a822439e8a4ac",
"/js/dist/all.js": "/js/dist/all.js?id=f68abd82226bf29870c0",
"/js/build/all.js": "/js/build/all.js?id=f68abd82226bf29870c0",
"/js/dist/bootstrap-table.js": "/js/dist/bootstrap-table.js?id=6804bda467f56a251e32",
"/js/dist/all.js": "/js/dist/all.js?id=8acd0023559eaaddd6c5",
"/js/build/all.js": "/js/build/all.js?id=8acd0023559eaaddd6c5",
"/js/dist/bootstrap-table.js": "/js/dist/bootstrap-table.js?id=7223478ba9bf2c6dfb4f",
"/js/dist/bootstrap-table-simple-view.js": "/js/dist/bootstrap-table-simple-view.js?id=3926b8f4aaad6ca20d31",
"/css/dist/bootstrap-table.css": "/css/dist/bootstrap-table.css?id=8340c60bfbc12c34d2e6"
}

View file

@ -1,34 +1,55 @@
<style>
tr {
tr {
padding-left:30px;
}
}
</style>
<template>
<tr v-show="processDetail">
<td colspan="3">
<td colspan="5">
<div class="col-md-2 text-left">
</div>
<div class="col-md-8 col-md-offset-2 text-center" style="padding-top: 30px; margin: 0 auto;">
<div class="col-md-12 text-left">
<h4 class="modal-title">Import File:</h4>
<div class="dynamic-form-row">
<div class="col-md-4 col-xs-12">
<div class="col-md-5 col-xs-12">
<label for="import-type">Import Type:</label>
</div>
<div class="col-md-4 col-xs-12">
<div class="col-md-7 col-xs-12">
<select2 :options="options.importTypes" v-model="options.importType" required>
<option disabled value="0"></option>
</select2>
</div>
</div>
<div class="dynamic-form-row">
<div class="col-md-4 col-xs-12">
<div class="col-md-5 col-xs-12">
<label for="import-update">Update Existing Values?:</label>
</div>
<div class="col-md-4 col-xs-12">
<div class="col-md-7 col-xs-12">
<input type="checkbox" name="import-update" v-model="options.update">
</div>
</div>
<div class="dynamic-form-row">
<div class="col-md-5 col-xs-12">
<label for="send-welcome">Send Welcome Email for new Users?</label>
</div>
<div class="col-md-7 col-xs-12">
<input type="checkbox" name="send-welcome" v-model="options.send_welcome">
</div>
</div>
</div>
<div class="alert col-md-12"
:class="alertClass"
style="text-align:left"
v-if="statusText">
{{ this.statusText }}
</div>
<div class="col-md-12" style="padding-top: 30px;">
<table class="table">
<div class="text-left" style="padding-top: 30px;">
<table class="table table-striped snipe-table">
<thead>
<th>Header Field</th>
<th>Import Field</th>
@ -54,21 +75,25 @@ tr {
</template>
</tbody>
</table>
</div>
</td>
<td>
<br>
<div class="col-md-8 col-md-offset-2 text-right">
<button type="button" class="btn btn-sm btn-default" @click="processDetail = false">Cancel</button>
<button type="submit" class="btn btn-sm btn-primary" @click="postSave">Import</button>
<div
class="alert col-md-5 col-md-offset-1"
<br><br>
</div>
<div class="alert col-md-12" style="padding-top: 20px;"
:class="alertClass"
style="text-align:left"
v-if="statusText"
>
v-if="statusText">
{{ this.statusText }}
</div>
</div>
</div>
</td>
</tr>
</template>
@ -143,7 +168,10 @@ tr {
{id: 'jobtitle', text: 'Job Title' },
{id: 'last_name', text: 'Last Name' },
{id: 'phone_number', text: 'Phone Number' },
{id: 'department', text: 'Department'}
{id: 'manager_first_name', text: 'Manager First Name' },
{id: 'manager_last_name', text: 'Manager Last Name' },
{id: 'department', text: 'Department' },
{id: 'activated', text: 'Activated' },
],
customFields: this.customFields,
@ -212,6 +240,7 @@ tr {
this.statusText = "Processing...";
this.$http.post(route('api.imports.importFile', this.file.id), {
'import-update': this.options.update,
'send-welcome': this.options.send_welcome,
'import-type': this.options.importType,
'column-mappings': this.columnMappings
}).then( ({body}) => {