Skip to content

Commit

Permalink
Features/add manager and dept to importer (snipe#6277)
Browse files Browse the repository at this point in the history
* Ignore the simlink for public storage

* Added manager and department to user import

* More UI importer tweaks

* Fisxed typos
  • Loading branch information
snipe authored Oct 2, 2018
1 parent 10bc35d commit c8bff3e
Show file tree
Hide file tree
Showing 17 changed files with 8,803 additions and 99 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,4 @@ tests/_support/_generated/*
/storage/oauth-public.key

*.cache
/public/storage
1 change: 1 addition & 0 deletions app/Console/Commands/ObjectImportCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ public function fire()
$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');
Expand Down
3 changes: 2 additions & 1 deletion app/Http/Requests/ItemImportRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ public function import(Import $import)
$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');
Expand All @@ -60,7 +61,7 @@ public function import(Import $import)

public function log($string)
{
// \Log::Info($string);
\Log::Info($string);
}

public function progress($count)
Expand Down
21 changes: 19 additions & 2 deletions app/Importer/Importer.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ abstract class Importer
'phone_number' => 'phone number',
'first_name' => 'first name',
'last_name' => 'last name',
'department' => 'department',
'manager_first_name' => 'manager first name',
'manager_last_name' => 'manager last name',
];
/**
* Map of item fields->csv names
Expand Down Expand Up @@ -176,7 +179,6 @@ public function findCsvMatch(array $array, $key, $default = null)
{

$val = $default;

$key = $this->lookupCustomKey($key);

$this->log("Custom Key: ${key}");
Expand All @@ -198,7 +200,6 @@ public function findCsvMatch(array $array, $key, $default = null)
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.
Expand Down Expand Up @@ -307,6 +308,8 @@ protected function createOrFetchUser($row)
$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;

Expand Down Expand Up @@ -360,6 +363,20 @@ public function setUpdating($updating)
return $this;
}

/**
* Sets the Are we updating items in the import.
*
* @param bool $updating the updating
*
* @return self
*/
public function setShouldNotify($send_welcome)
{
$this->send_welcome = $send_welcome;

return $this;
}

/**
* Defines mappings of csv fields
*
Expand Down
65 changes: 63 additions & 2 deletions app/Importer/ItemImporter.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use App\Models\Manufacturer;
use App\Models\Statuslabel;
use App\Models\Supplier;
use App\Models\Department;
use App\Models\User;

class ItemImporter extends Importer
Expand Down Expand Up @@ -54,6 +55,18 @@ protected function handle($row)
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, "manager_first_name");
$item_manager_last_name = $this->findCsvMatch($row, "manager_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");
Expand Down Expand Up @@ -84,7 +97,7 @@ protected function handle($row)
*/
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);
}
Expand Down Expand Up @@ -161,7 +174,7 @@ private function shouldUpdateField($field)
* @since 3.0
* @param array
* @param $category Category
* @param $manufacturer Manufacturer
* @param $row Manufacturer
* @return int Id of asset model created/found
* @internal param $asset_modelno string
*/
Expand Down Expand Up @@ -279,6 +292,54 @@ public function createOrFetchCompany($asset_company_name)
return null;
}

/**
* Fetch an existing department, or create new if it doesn't exist
*
* @author A. Gianotto
* @since 4.6.5
* @param $user_department string
* @return int id of company created/found
*/
public function createOrFetchDepartment($user_department_name)
{
$department = Department::where('name', '=', $user_department_name)->first();

if ($department) {
$this->log('A matching Department ' . $user_department_name . ' already exists');
return $department->id;
}

$department = new Department();
$department->name = $user_department_name;

if ($department->save()) {
$this->log('Department ' . $user_department_name . ' was created');
return $department->id;
}
$this->logError($department, 'Department');
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.
*
Expand Down
14 changes: 10 additions & 4 deletions app/Importer/UserImporter.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ class UserImporter extends ItemImporter
public function __construct($filename)
{
parent::__construct($filename);
// $this->users = User::all();
}

protected function handle($row)
Expand All @@ -31,14 +30,18 @@ protected function handle($row)
*/
public function createUserIfNotExists(array $row)
{
// User Specific Bits
$this->item['username'] = $this->findCsvMatch($row, 'username');
$this->item['first_name'] = $this->findCsvMatch($row, 'first_name');
$this->item['last_name'] = $this->findCsvMatch($row, 'last_name');
$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 = User::where('username', $this->item['username'])->first();
if ($user) {
if (!$this->updating) {
Expand All @@ -50,6 +53,7 @@ public function createUserIfNotExists(array $row)
$user->save();
return;
}

// This needs to be applied after the update logic, otherwise we'll overwrite user passwords
// Issue #5408
$this->item['password'] = $this->tempPassword;
Expand All @@ -58,7 +62,6 @@ public function createUserIfNotExists(array $row)
$user = new User();
$user->fill($this->sanitizeItemForStoring($user));
if ($user->save()) {
// $user->logCreate('Imported using CSV Importer');
$this->log("User " . $this->item["name"] . ' was created');
if($user->email) {
$data = [
Expand All @@ -70,7 +73,10 @@ public function createUserIfNotExists(array $row)
];

// UNCOMMENT this to re-enable sending email notifications on user import
// $user->notify(new WelcomeNotification($data));
if ($this->send_welcome) {
$user->notify(new WelcomeNotification($data));
}

}
$user = null;
$this->item = null;
Expand Down
16 changes: 10 additions & 6 deletions app/Importer/import_mappings.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
| CSV | Item | Applicable Types |
|---------------------|------------------|-------------------------------------------|
| activated | | User |
| asset tag | asset_tag | Asset |
| category | category | All |
| company | company | All |
| department_id | | User ? All |
| item name | item_name | All |
| image | image | asset |
| image | image | Asset |
| email | | |
| 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 |
Expand All @@ -22,12 +26,12 @@
| 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 | | |
| username | | |
| username | | |

10 changes: 5 additions & 5 deletions app/Models/Department.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ class Department extends SnipeModel
use ValidatingTrait, UniqueUndeletedTrait;

protected $rules = [
'name' => 'required|max:255',
'user_id' => 'required',
'location_id' => 'numeric|nullable',
'company_id' => 'numeric|nullable',
'manager_id' => 'numeric|nullable',
'name' => 'required|max:255',
'user_id' => 'nullable|exists:users,id',
'location_id' => 'numeric|nullable',
'company_id' => 'numeric|nullable',
'manager_id' => 'numeric|nullable',
];

/**
Expand Down
605 changes: 600 additions & 5 deletions public/css/build/all.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion public/css/dist/all.css

Large diffs are not rendered by default.

8,040 changes: 8,014 additions & 26 deletions public/js/build/all.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion public/js/build/vue.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion public/js/build/vue.js.map

Large diffs are not rendered by default.

40 changes: 20 additions & 20 deletions public/js/dist/all.js

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions public/mix-manifest.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
{
"/js/build/vue.js": "/js/build/vue.js?id=832c22cb5b66ac81ed06",
"/js/build/vue.js": "/js/build/vue.js?id=94cc644b10b5436da8ef",
"/css/AdminLTE.css": "/css/AdminLTE.css?id=5e72463a66acbcc740d5",
"/css/app.css": "/css/app.css?id=407edb63cc6b6dc62405",
"/css/overrides.css": "/css/overrides.css?id=2d81c3704393bac77011",
"/js/build/vue.js.map": "/js/build/vue.js.map?id=0deaf852882fe2d65263",
"/js/build/vue.js.map": "/js/build/vue.js.map?id=d2f525f3411031bec8a0",
"/css/AdminLTE.css.map": "/css/AdminLTE.css.map?id=0be7790b84909dca6a0a",
"/css/app.css.map": "/css/app.css.map?id=96b5c985e860716e6a16",
"/css/overrides.css.map": "/css/overrides.css.map?id=f7ce9ca49027594ac402",
"/css/dist/all.css": "/css/dist/all.css?id=98db4e9b7650453c8b00",
"/js/dist/all.js": "/js/dist/all.js?id=9d02373ef452329336d3",
"/js/dist/all.js": "/js/dist/all.js?id=15c1c83483171165eb54",
"/css/build/all.css": "/css/build/all.css?id=98db4e9b7650453c8b00",
"/js/build/all.js": "/js/build/all.js?id=9d02373ef452329336d3"
}
"/js/build/all.js": "/js/build/all.js?id=15c1c83483171165eb54"
}
Loading

0 comments on commit c8bff3e

Please sign in to comment.