mirror of
https://github.com/snipe/snipe-it.git
synced 2024-12-24 05:04:07 -08:00
Importer rework (#3100)
* Step 1 of refactoring importer to use separate classes. * Port web importer. Fix an issue with validation where index 0 would be treated as false and cause weird results. * Farewall, AssetImport. You've served us well.
This commit is contained in:
parent
8857faee65
commit
57374955a8
|
@ -1,463 +0,0 @@
|
|||
<?php
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Models\Location;
|
||||
use App\Models\Category;
|
||||
use App\Models\AssetModel;
|
||||
use App\Models\Company;
|
||||
use App\Models\Asset;
|
||||
use App\Models\Manufacturer;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use League\Csv\Reader;
|
||||
|
||||
class AssetImportCommand extends Command
|
||||
{
|
||||
|
||||
/**
|
||||
* The console command name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $name = 'snipeit:asset-import';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Import Assets from CSV';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function fire()
|
||||
{
|
||||
$filename = $this->argument('filename');
|
||||
|
||||
|
||||
if (!$this->option('testrun')=='true') {
|
||||
$this->comment('======= Importing Assets from '.$filename.' =========');
|
||||
} else {
|
||||
$this->comment('====== TEST ONLY Asset Import for '.$filename.' ====');
|
||||
$this->comment('============== NO DATA WILL BE WRITTEN ==============');
|
||||
}
|
||||
|
||||
if (! ini_get("auto_detect_line_endings")) {
|
||||
ini_set("auto_detect_line_endings", '1');
|
||||
}
|
||||
|
||||
$csv = Reader::createFromPath($this->argument('filename'));
|
||||
$csv->setNewline("\r\n");
|
||||
$csv->setOffset(1);
|
||||
$duplicates = '';
|
||||
|
||||
// Loop through the records
|
||||
$nbInsert = $csv->each(function ($row) use ($duplicates) {
|
||||
$status_id = 1;
|
||||
|
||||
// Let's just map some of these entries to more user friendly words
|
||||
|
||||
// User's name
|
||||
if (array_key_exists('0', $row)) {
|
||||
$user_name = trim($row[0]);
|
||||
} else {
|
||||
$user_name = '';
|
||||
}
|
||||
|
||||
// User's email
|
||||
if (array_key_exists('1', $row)) {
|
||||
$user_email = trim($row[1]);
|
||||
} else {
|
||||
$user_email = '';
|
||||
}
|
||||
|
||||
// User's email
|
||||
if (array_key_exists('2', $row)) {
|
||||
$user_username = trim($row[2]);
|
||||
} else {
|
||||
$user_username = '';
|
||||
}
|
||||
|
||||
// Asset Name
|
||||
if (array_key_exists('3', $row)) {
|
||||
$user_asset_asset_name = trim($row[3]);
|
||||
} else {
|
||||
$user_asset_asset_name = '';
|
||||
}
|
||||
|
||||
// Asset Category
|
||||
if (array_key_exists('4', $row)) {
|
||||
$user_asset_category = trim($row[4]);
|
||||
} else {
|
||||
$user_asset_category = '';
|
||||
}
|
||||
|
||||
// Asset Name
|
||||
if (array_key_exists('5', $row)) {
|
||||
$user_asset_name = trim($row[5]);
|
||||
} else {
|
||||
$user_asset_name = '';
|
||||
}
|
||||
|
||||
// Asset Manufacturer
|
||||
if (array_key_exists('6', $row)) {
|
||||
$user_asset_mfgr = trim($row[6]);
|
||||
} else {
|
||||
$user_asset_mfgr = '';
|
||||
}
|
||||
|
||||
// Asset model number
|
||||
if (array_key_exists('7', $row)) {
|
||||
$user_asset_modelno = trim($row[7]);
|
||||
} else {
|
||||
$user_asset_modelno = '';
|
||||
}
|
||||
|
||||
// Asset serial number
|
||||
if (array_key_exists('8', $row)) {
|
||||
$user_asset_serial = trim($row[8]);
|
||||
} else {
|
||||
$user_asset_serial = '';
|
||||
}
|
||||
|
||||
// Asset tag
|
||||
if (array_key_exists('9', $row)) {
|
||||
$user_asset_tag = trim($row[9]);
|
||||
} else {
|
||||
$user_asset_tag = '';
|
||||
}
|
||||
|
||||
// Asset location
|
||||
if (array_key_exists('10', $row)) {
|
||||
$user_asset_location = trim($row[10]);
|
||||
} else {
|
||||
$user_asset_location = '';
|
||||
}
|
||||
|
||||
// Asset notes
|
||||
if (array_key_exists('11', $row)) {
|
||||
$user_asset_notes = trim($row[11]);
|
||||
} else {
|
||||
$user_asset_notes = '';
|
||||
}
|
||||
|
||||
// Asset purchase date
|
||||
if (array_key_exists('12', $row)) {
|
||||
if ($row[12]!='') {
|
||||
$user_asset_purchase_date = date("Y-m-d 00:00:01", strtotime($row[12]));
|
||||
} else {
|
||||
$user_asset_purchase_date = '';
|
||||
}
|
||||
} else {
|
||||
$user_asset_purchase_date = '';
|
||||
}
|
||||
|
||||
// Asset purchase cost
|
||||
if (array_key_exists('13', $row)) {
|
||||
if ($row[13]!='') {
|
||||
$user_asset_purchase_cost = trim($row[13]);
|
||||
} else {
|
||||
$user_asset_purchase_cost = '';
|
||||
}
|
||||
} else {
|
||||
$user_asset_purchase_cost = '';
|
||||
}
|
||||
|
||||
// Asset Company Name
|
||||
if (array_key_exists('14', $row)) {
|
||||
if ($row[14]!='') {
|
||||
$user_asset_company_name = trim($row[14]);
|
||||
} else {
|
||||
$user_asset_company_name= '';
|
||||
}
|
||||
} else {
|
||||
$user_asset_company_name = '';
|
||||
}
|
||||
|
||||
|
||||
// A number was given instead of a name
|
||||
if (is_numeric($user_name)) {
|
||||
$this->comment('User '.$user_name.' is not a name - assume this user already exists');
|
||||
$user_username = '';
|
||||
$first_name = '';
|
||||
$last_name = '';
|
||||
|
||||
// No name was given
|
||||
} elseif ($user_name=='') {
|
||||
$this->comment('No user data provided - skipping user creation, just adding asset');
|
||||
$first_name = '';
|
||||
$last_name = '';
|
||||
//$user_username = '';
|
||||
|
||||
} else {
|
||||
$user_email_array = User::generateFormattedNameFromFullName($this->option('email_format'), $user_name);
|
||||
$first_name = $user_email_array['first_name'];
|
||||
$last_name = $user_email_array['last_name'];
|
||||
|
||||
if ($user_email=='') {
|
||||
$user_email = $user_email_array['username'].'@'.config('app.domain');
|
||||
}
|
||||
|
||||
if ($user_username=='') {
|
||||
if ($this->option('username_format')=='email') {
|
||||
$user_username = $user_email;
|
||||
} else {
|
||||
$user_name_array = User::generateFormattedNameFromFullName($this->option('username_format'), $user_name);
|
||||
$user_username = $user_name_array['username'];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$this->comment('Full Name: '.$user_name);
|
||||
$this->comment('First Name: '.$first_name);
|
||||
$this->comment('Last Name: '.$last_name);
|
||||
$this->comment('Username: '.$user_username);
|
||||
$this->comment('Email: '.$user_email);
|
||||
$this->comment('Category Name: '.$user_asset_category);
|
||||
$this->comment('Item: '.$user_asset_name);
|
||||
$this->comment('Manufacturer ID: '.$user_asset_mfgr);
|
||||
$this->comment('Model No: '.$user_asset_modelno);
|
||||
$this->comment('Serial No: '.$user_asset_serial);
|
||||
$this->comment('Asset Tag: '.$user_asset_tag);
|
||||
$this->comment('Location: '.$user_asset_location);
|
||||
$this->comment('Purchase Date: '.$user_asset_purchase_date);
|
||||
$this->comment('Purchase Cost: '.$user_asset_purchase_cost);
|
||||
$this->comment('Notes: '.$user_asset_notes);
|
||||
$this->comment('Company Name: '.$user_asset_company_name);
|
||||
|
||||
$this->comment('------------- Action Summary ----------------');
|
||||
|
||||
if ($user_username!='') {
|
||||
if ($user = User::MatchEmailOrUsername($user_username, $user_email)
|
||||
->whereNotNull('username')->first()) {
|
||||
$this->comment('User '.$user_username.' already exists');
|
||||
} else {
|
||||
$user = new \App\Models\User;
|
||||
$password = substr(str_shuffle("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), 0, 20);
|
||||
|
||||
$user->first_name = $first_name;
|
||||
$user->last_name = $last_name;
|
||||
$user->username = $user_username;
|
||||
$user->email = $user_email;
|
||||
$user->permissions = '{user":1}';
|
||||
$user->password = bcrypt($password);
|
||||
$user->activated = 1;
|
||||
if ($user->save()) {
|
||||
$this->comment('User '.$first_name.' created');
|
||||
} else {
|
||||
$this->error('ERROR CREATING User '.$first_name.' '.$last_name);
|
||||
$this->error($user->getErrors());
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
$user = new User;
|
||||
}
|
||||
|
||||
// Check for the location match and create it if it doesn't exist
|
||||
if ($location = Location::where('name', e($user_asset_location))->first()) {
|
||||
$this->comment('Location '.$user_asset_location.' already exists');
|
||||
} else {
|
||||
|
||||
$location = new Location();
|
||||
|
||||
if ($user_asset_location!='') {
|
||||
$location->name = e($user_asset_location);
|
||||
$location->address = '';
|
||||
$location->city = '';
|
||||
$location->state = '';
|
||||
$location->country = '';
|
||||
$location->user_id = 1;
|
||||
|
||||
if (!$this->option('testrun')=='true') {
|
||||
|
||||
if ($location->save()) {
|
||||
$this->comment('Location '.$user_asset_location.' was created');
|
||||
} else {
|
||||
$this->error('Something went wrong! Location '.$user_asset_location.' was NOT created');
|
||||
$this->error($location->getErrors());
|
||||
}
|
||||
|
||||
} else {
|
||||
$this->comment('Location '.$user_asset_location.' was (not) created - test run only');
|
||||
}
|
||||
} else {
|
||||
$this->comment('No location given, so none created.');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (e($user_asset_category)=='') {
|
||||
$category_name = 'Unnamed Category';
|
||||
} else {
|
||||
$category_name = e($user_asset_category);
|
||||
}
|
||||
|
||||
// Check for the category match and create it if it doesn't exist
|
||||
if ($category = Category::where('name', e($category_name))->where('category_type', 'asset')->first()) {
|
||||
$this->comment('Category '.$category_name.' already exists');
|
||||
|
||||
} else {
|
||||
$category = new Category();
|
||||
$category->name = e($category_name);
|
||||
$category->category_type = 'asset';
|
||||
$category->user_id = 1;
|
||||
|
||||
if ($category->save()) {
|
||||
$this->comment('Category '.$user_asset_category.' was created');
|
||||
} else {
|
||||
$this->error('Something went wrong! Category '.$user_asset_category.' was NOT created');
|
||||
$this->error($category->getErrors());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Check for the manufacturer match and create it if it doesn't exist
|
||||
if ($manufacturer = Manufacturer::where('name', e($user_asset_mfgr))->first()) {
|
||||
$this->comment('Manufacturer '.$user_asset_mfgr.' already exists');
|
||||
} else {
|
||||
$manufacturer = new Manufacturer();
|
||||
$manufacturer->name = e($user_asset_mfgr);
|
||||
$manufacturer->user_id = 1;
|
||||
|
||||
if ($manufacturer->save()) {
|
||||
$this->comment('Manufacturer '.$user_asset_mfgr.' was created');
|
||||
} else {
|
||||
$this->error('Something went wrong! Manufacturer '.$user_asset_mfgr.' was NOT created: '. $manufacturer->getErrors()->first());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Check for the asset model match and create it if it doesn't exist
|
||||
if ($asset_model = AssetModel::where('name', e($user_asset_name))->where('modelno', e($user_asset_modelno))->where('category_id', $category->id)->where('manufacturer_id', $manufacturer->id)->first()) {
|
||||
$this->comment('The Asset Model '.$user_asset_name.' with model number '.$user_asset_modelno.' already exists');
|
||||
} else {
|
||||
$asset_model = new AssetModel();
|
||||
$asset_model->name = e($user_asset_name);
|
||||
$asset_model->manufacturer_id = $manufacturer->id;
|
||||
$asset_model->modelno = e($user_asset_modelno);
|
||||
$asset_model->category_id = $category->id;
|
||||
$asset_model->user_id = 1;
|
||||
|
||||
if ($asset_model->save()) {
|
||||
$this->comment('Asset Model '.$user_asset_name.' with model number '.$user_asset_modelno.' was created');
|
||||
} else {
|
||||
$this->error('Something went wrong! Asset Model '.$user_asset_name.' was NOT created: '.$asset_model->getErrors()->first());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Check for the asset company match and create it if it doesn't exist
|
||||
if ($user_asset_company_name!='') {
|
||||
if ($company = Company::where('name', e($user_asset_company_name))->first()) {
|
||||
$this->comment('Company '.$user_asset_company_name.' already exists');
|
||||
} else {
|
||||
$company = new Company();
|
||||
$company->name = e($user_asset_company_name);
|
||||
|
||||
if ($company->save()) {
|
||||
$this->comment('Company '.$user_asset_company_name.' was created');
|
||||
} else {
|
||||
$this->error('Something went wrong! Company '.$user_asset_company_name.' was NOT created: '.$company->getErrors()->first());
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
$company = new Company();
|
||||
}
|
||||
|
||||
// Check for the asset match and create it if it doesn't exist
|
||||
if ($asset = Asset::where('asset_tag', e($user_asset_tag))->first()) {
|
||||
$this->comment('The Asset with asset tag '.$user_asset_tag.' already exists');
|
||||
} else {
|
||||
$asset = new Asset();
|
||||
$asset->name = e($user_asset_asset_name);
|
||||
if ($user_asset_purchase_date!='') {
|
||||
$asset->purchase_date = $user_asset_purchase_date;
|
||||
} else {
|
||||
$asset->purchase_date = null;
|
||||
}
|
||||
if ($user_asset_purchase_cost!='') {
|
||||
$asset->purchase_cost = ParseFloat(e($user_asset_purchase_cost));
|
||||
} else {
|
||||
$asset->purchase_cost = 0.00;
|
||||
}
|
||||
$asset->serial = e($user_asset_serial);
|
||||
$asset->asset_tag = e($user_asset_tag);
|
||||
$asset->model_id = $asset_model->id;
|
||||
$asset->assigned_to = $user->id;
|
||||
$asset->rtd_location_id = $location->id;
|
||||
$asset->user_id = 1;
|
||||
$asset->status_id = $status_id;
|
||||
$asset->company_id = $company->id;
|
||||
if ($user_asset_purchase_date!='') {
|
||||
$asset->purchase_date = $user_asset_purchase_date;
|
||||
} else {
|
||||
$asset->purchase_date = null;
|
||||
}
|
||||
$asset->notes = e($user_asset_notes);
|
||||
|
||||
if ($asset->save()) {
|
||||
$this->comment('Asset '.$user_asset_name.' with serial number '.$user_asset_serial.' was created');
|
||||
} else {
|
||||
$this->error('Something went wrong! Asset '.$user_asset_name.' was NOT created: '.$asset->getErrors()->first());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
$this->comment('=====================================');
|
||||
|
||||
return true;
|
||||
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the console command arguments.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getArguments()
|
||||
{
|
||||
return array(
|
||||
array('filename', InputArgument::REQUIRED, 'File for the CSV import.'),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the console command options.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getOptions()
|
||||
{
|
||||
return array(
|
||||
array('email_format', null, InputOption::VALUE_REQUIRED, 'The format of the email addresses that should be generated. Options are firstname.lastname, firstname, filastname', null),
|
||||
array('username_format', null, InputOption::VALUE_REQUIRED, 'The format of the username that should be generated. Options are firstname.lastname, firstname, filastname, email', null),
|
||||
array('testrun', null, InputOption::VALUE_REQUIRED, 'Test the output without writing to the database or not.', null),
|
||||
);
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -6,6 +6,7 @@ use App\Http\Requests\AssetCheckinRequest;
|
|||
use App\Http\Requests\AssetCheckoutRequest;
|
||||
use App\Http\Requests\AssetFileRequest;
|
||||
use App\Http\Requests\AssetRequest;
|
||||
use App\Http\Requests\ItemImportRequest;
|
||||
use App\Models\Actionlog;
|
||||
use App\Models\Asset;
|
||||
use App\Models\AssetMaintenance;
|
||||
|
@ -853,46 +854,29 @@ class AssetsController extends Controller
|
|||
* @since [v2.0]
|
||||
* @return Redirect
|
||||
*/
|
||||
public function postProcessImportFile()
|
||||
public function postProcessImportFile(ItemImportRequest $request)
|
||||
{
|
||||
// php artisan asset-import:csv path/to/your/file.csv --domain=yourdomain.com --email_format=firstname.lastname
|
||||
$filename = config('app.private_uploads') . '/imports/assets/' . request('filename');
|
||||
$this->authorize('create', Asset::class);
|
||||
$importOptions = ['filename'=> $filename,
|
||||
'--email_format'=>'firstname.lastname',
|
||||
'--username_format'=>'firstname.lastname',
|
||||
'--web-importer' => true,
|
||||
'--user_id' => Auth::id(),
|
||||
'--item-type' => request('import-type'),
|
||||
];
|
||||
if (request('import-update')) {
|
||||
$importOptions['--update'] = true;
|
||||
}
|
||||
$errors = $request->import();
|
||||
|
||||
$return = Artisan::call('snipeit:import', $importOptions);
|
||||
$display_output = Artisan::output();
|
||||
$file = config('app.private_uploads').'/imports/assets/'.str_replace('.csv', '', $filename).'-output-'.date("Y-m-d-his").'.txt';
|
||||
file_put_contents($file, $display_output);
|
||||
// We use hardware instead of asset in the url
|
||||
$redirectTo = "hardware";
|
||||
switch(request('import-type')) {
|
||||
case "asset":
|
||||
$redirectTo = "hardware";
|
||||
$redirectTo = "hardware.index";
|
||||
break;
|
||||
case "accessory":
|
||||
$redirectTo = "accessories";
|
||||
$redirectTo = "accessories.index";
|
||||
break;
|
||||
case "consumable":
|
||||
$redirectTo = "consumables";
|
||||
$redirectTo = "consumables.index";
|
||||
break;
|
||||
}
|
||||
|
||||
if ($return === 0) { //Success
|
||||
return redirect()->to(route($redirectTo))->with('success', trans('admin/hardware/message.import.success'));
|
||||
} elseif ($return === 1) { // Failure
|
||||
return redirect()->back()->with('import_errors', json_decode($display_output))->with('error', trans('admin/hardware/message.import.error'));
|
||||
if ($errors) { //Failure
|
||||
return redirect()->back()->with('import_errors', json_decode(json_encode($errors)))->with('error', trans('admin/hardware/message.import.error'));
|
||||
}
|
||||
dd("Shouldn't be here");
|
||||
return redirect()->to(route($redirectTo))->with('success', trans('admin/hardware/message.import.success'));
|
||||
|
||||
}
|
||||
|
||||
|
|
83
app/Http/Requests/ItemImportRequest.php
Normal file
83
app/Http/Requests/ItemImportRequest.php
Normal file
|
@ -0,0 +1,83 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class ItemImportRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
|
||||
public function import()
|
||||
{
|
||||
$filename = config('app.private_uploads') . '/imports/assets/' . $this->get('filename');
|
||||
|
||||
$importerClass = Importer::class;
|
||||
switch ($this->get('import-type')) {
|
||||
case "asset":
|
||||
$importerClass = 'App\Importer\AssetImporter';
|
||||
break;
|
||||
case "accessory":
|
||||
$importerClass = 'App\Importer\AccessoryImporter';
|
||||
break;
|
||||
case "component":
|
||||
die("This is not implemented yet");
|
||||
$importerClass = ComponentImporter::class;
|
||||
break;
|
||||
case "consumable":
|
||||
$importerClass = 'App\Importer\ConsumableImporter';
|
||||
break;
|
||||
}
|
||||
$importer = new $importerClass(
|
||||
$filename,
|
||||
[$this, 'log'],
|
||||
[$this, 'progress'],
|
||||
[$this, 'errorCallback'],
|
||||
false, /*testrun*/
|
||||
Auth::id(),
|
||||
$this->has('import-update'),
|
||||
'firstname.lastname'
|
||||
);
|
||||
|
||||
$importer->import();
|
||||
return $this->errors;
|
||||
}
|
||||
|
||||
public function log($string)
|
||||
{
|
||||
return; // FUTURE IMPLEMENTATION
|
||||
}
|
||||
|
||||
public function progress($count)
|
||||
{
|
||||
// Open for future
|
||||
return;
|
||||
}
|
||||
public function errorCallback($item, $field, $errorString)
|
||||
{
|
||||
$this->errors[$item->name][$field] = $errorString;
|
||||
}
|
||||
|
||||
private $errors;
|
||||
}
|
110
app/Importer/AccessoryImporter.php
Normal file
110
app/Importer/AccessoryImporter.php
Normal file
|
@ -0,0 +1,110 @@
|
|||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: parallelgrapefruit
|
||||
* Date: 12/24/16
|
||||
* Time: 12:56 PM
|
||||
*/
|
||||
|
||||
namespace App\Importer;
|
||||
|
||||
|
||||
use App\Helpers\Helper;
|
||||
use App\Models\Accessory;
|
||||
|
||||
class AccessoryImporter extends ItemImporter
|
||||
{
|
||||
protected $accessories;
|
||||
function __construct($filename, $logCallback, $progressCallback, $errorCallback, $testRun = false, $user_id = -1, $updating = false, $usernameFormat = null)
|
||||
{
|
||||
parent::__construct($filename, $logCallback, $progressCallback, $errorCallback, $testRun, $user_id, $updating, $usernameFormat);
|
||||
$this->accessories = Accessory::all();
|
||||
}
|
||||
|
||||
protected function handle($row)
|
||||
{
|
||||
parent::handle($row); // TODO: Change the autogenerated stub
|
||||
$this->createAccessoryIfNotExists();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an accessory if a duplicate does not exist
|
||||
*
|
||||
* @author Daniel Melzter
|
||||
* @since 3.0
|
||||
*/
|
||||
public function createAccessoryIfNotExists()
|
||||
{
|
||||
$accessory = null;
|
||||
$editingAccessory = false;
|
||||
$this->log("Creating Accessory");
|
||||
$accessory = $this->accessories->search(function ($key) {
|
||||
return strcasecmp($key->name, $this->item['item_name']) == 0;
|
||||
});
|
||||
if($accessory) {
|
||||
$editingAccessory = true;
|
||||
if (!$this->updating) {
|
||||
$this->log('A matching Accessory ' . $this->item["item_name"] . ' already exists. ');
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
$this->log("No Matching Accessory, Creating a new one");
|
||||
$accessory = new Accessory();
|
||||
}
|
||||
|
||||
if (!$editingAccessory) {
|
||||
$accessory->name = $this->item["item_name"];
|
||||
}
|
||||
|
||||
if (!empty($this->item["purchase_date"])) {
|
||||
$accessory->purchase_date = $this->item["purchase_date"];
|
||||
} else {
|
||||
$accessory->purchase_date = null;
|
||||
}
|
||||
if (!empty($this->item["purchase_cost"])) {
|
||||
$accessory->purchase_cost = Helper::ParseFloat($this->item["purchase_cost"]);
|
||||
}
|
||||
|
||||
if (isset($this->item["location"])) {
|
||||
$accessory->location_id = $this->item["location"]->id;
|
||||
}
|
||||
$accessory->user_id = $this->user_id;
|
||||
if (isset($this->item["company"])) {
|
||||
$accessory->company_id = $this->item["company"]->id;
|
||||
}
|
||||
if (!empty($this->item["order_number"])) {
|
||||
$accessory->order_number = $this->item["order_number"];
|
||||
}
|
||||
if (isset($this->item["category"])) {
|
||||
$accessory->category_id = $this->item["category"]->id;
|
||||
}
|
||||
|
||||
//TODO: Implement
|
||||
// $accessory->notes = e($item_notes);
|
||||
if (!empty($this->item["requestable"])) {
|
||||
$accessory->requestable = filter_var($this->item["requestable"], FILTER_VALIDATE_BOOLEAN);
|
||||
}
|
||||
|
||||
//Must have at least zero of the item if we import it.
|
||||
if (!empty($this->item["quantity"])) {
|
||||
if ($this->item["quantity"] > -1) {
|
||||
$accessory->qty = $this->item["quantity"];
|
||||
} else {
|
||||
$accessory->qty = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$this->testRun) {
|
||||
if ($accessory->save()) {
|
||||
$accessory->logCreate('Imported using CSV Importer');
|
||||
$this->log('Accessory ' . $this->item["item_name"] . ' was created');
|
||||
// $this->comment('Accessory ' . $this->item["item_name"] . ' was created');
|
||||
|
||||
} else {
|
||||
$this->jsonError($accessory,'Accessory', $accessory->getErrors()) ;
|
||||
}
|
||||
} else {
|
||||
$this->log('TEST RUN - Accessory ' . $this->item["item_name"] . ' not created');
|
||||
}
|
||||
}
|
||||
}
|
176
app/Importer/AssetImporter.php
Normal file
176
app/Importer/AssetImporter.php
Normal file
|
@ -0,0 +1,176 @@
|
|||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: parallelgrapefruit
|
||||
* Date: 12/24/16
|
||||
* Time: 12:45 PM
|
||||
*/
|
||||
|
||||
namespace App\Importer;
|
||||
|
||||
|
||||
use App\Helpers\Helper;
|
||||
use App\Models\Asset;
|
||||
use App\Models\Category;
|
||||
use App\Models\Manufacturer;
|
||||
|
||||
class AssetImporter extends ItemImporter
|
||||
{
|
||||
protected $assets;
|
||||
function __construct($filename, $logCallback, $progressCallback, $errorCallback, $testRun = false, $user_id = -1, $updating = false, $usernameFormat = null)
|
||||
{
|
||||
parent::__construct($filename, $logCallback, $progressCallback, $errorCallback, $testRun, $user_id, $updating, $usernameFormat);
|
||||
$this->assets = Asset::all();
|
||||
}
|
||||
|
||||
protected function handle($row)
|
||||
{
|
||||
// ItemImporter handles the general fetching.
|
||||
parent::handle($row);
|
||||
|
||||
foreach ($this->customFields as $customField) {
|
||||
if ($this->item['custom_fields'][$customField->db_column_name()] = $this->array_smart_custom_field_fetch($row, $customField)) {
|
||||
$this->log('Custom Field '. $customField->name.': '.$this->array_smart_custom_field_fetch($row, $customField));
|
||||
}
|
||||
}
|
||||
|
||||
$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)
|
||||
{
|
||||
$asset = null;
|
||||
$editingAsset = false;
|
||||
$asset = $this->assets->search(function ($key) {
|
||||
return strcasecmp($key->asset_tag, $this->item['asset_tag']) == 0;
|
||||
});
|
||||
if($asset) {
|
||||
$editingAsset = true;
|
||||
if (!$this->updating) {
|
||||
$this->log('A matching Asset ' . $this->item['asset_tag'] . ' already exists');
|
||||
return $asset;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$asset) {
|
||||
$this->log("No Matching Asset, Creating a new one");
|
||||
$asset = new Asset;
|
||||
}
|
||||
$asset_serial = $this->array_smart_fetch($row, "serial number");
|
||||
$asset_image = $this->array_smart_fetch($row, "image");
|
||||
$asset_warranty_months = intval($this->array_smart_fetch($row, "warranty months"));
|
||||
if (empty($asset_warranty_months)) {
|
||||
$asset_warranty_months = null;
|
||||
}
|
||||
// Check for the asset model match and create it if it doesn't exist
|
||||
if (!($editingAsset && empty($this->array_smart_fetch($row, 'model name')))) {
|
||||
// Ignore the asset_model
|
||||
isset($this->item["category"]) || $this->item["category"] = new Category();
|
||||
isset($this->item["manufacturer"]) || $this->item["manufacturer"] = new Manufacturer();
|
||||
$asset_model = $this->createOrFetchAssetModel($row, $this->item["category"], $this->item["manufacturer"]);
|
||||
}
|
||||
$item_supplier = $this->array_smart_fetch($row, "supplier");
|
||||
// If we're editing, only update if value isn't empty
|
||||
if (!($editingAsset && empty($item_supplier))) {
|
||||
$supplier = $this->createOrFetchSupplier($item_supplier);
|
||||
}
|
||||
|
||||
$this->log('Serial No: '.$asset_serial);
|
||||
$this->log('Asset Tag: '.$this->item['asset_tag']);
|
||||
$this->log('Notes: '.$this->item["notes"]);
|
||||
$this->log('Warranty Months: ' . $asset_warranty_months);
|
||||
|
||||
|
||||
if (isset($this->item["status_label"])) {
|
||||
$status_id = $this->item["status_label"]->id;
|
||||
} else if (!$editingAsset) {
|
||||
// Assume if we are editing, we already have a status and can ignore.
|
||||
$this->log("No status field found, defaulting to first status.");
|
||||
$status_id = $this->status_labels->first()->id;
|
||||
}
|
||||
|
||||
if (!$editingAsset) {
|
||||
$asset->asset_tag = $this->item['asset_tag']; // This doesn't need to be guarded for empty because it's the key we use to identify the asset.
|
||||
}
|
||||
if (!empty($this->item['item_name'])) {
|
||||
$asset->name = $this->item["item_name"];
|
||||
}
|
||||
if (!empty($this->item["purchase_date"])) {
|
||||
$asset->purchase_date = $this->item["purchase_date"];
|
||||
}
|
||||
|
||||
if (array_key_exists('custom_fields', $this->item)) {
|
||||
foreach ($this->item['custom_fields'] as $custom_field => $val) {
|
||||
$asset->{$custom_field} = $val;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($this->item["purchase_cost"])) {
|
||||
//TODO How to generalize this for not USD?
|
||||
$purchase_cost = substr($this->item["purchase_cost"], 0, 1) === '$' ? substr($this->item["purchase_cost"], 1) : $this->item["purchase_cost"];
|
||||
// $asset->purchase_cost = number_format($purchase_cost, 2, '.', '');
|
||||
$asset->purchase_cost = Helper::ParseFloat($purchase_cost);
|
||||
$this->log("Asset cost parsed: " . $asset->purchase_cost);
|
||||
} else {
|
||||
$asset->purchase_cost = 0.00;
|
||||
}
|
||||
if (!empty($asset_serial)) {
|
||||
$asset->serial = $asset_serial;
|
||||
}
|
||||
if (!empty($asset_warranty_months)) {
|
||||
$asset->warranty_months = $asset_warranty_months;
|
||||
}
|
||||
|
||||
if (isset($asset_model)) {
|
||||
$asset->model_id = $asset_model->id;
|
||||
}
|
||||
|
||||
if ($this->item["user"]) {
|
||||
$asset->assigned_to = $this->item["user"]->id;
|
||||
}
|
||||
|
||||
if (isset($this->item["location"])) {
|
||||
$asset->rtd_location_id = $this->item["location"]->id;
|
||||
}
|
||||
|
||||
$asset->user_id = $this->user_id;
|
||||
if (isset($status_id)) {
|
||||
$asset->status_id = $status_id;
|
||||
}
|
||||
if (isset($this->item["company"])) {
|
||||
$asset->company_id = $this->item["company"]->id;
|
||||
}
|
||||
if ($this->item["order_number"]) {
|
||||
$asset->order_number = $this->item["order_number"];
|
||||
}
|
||||
|
||||
if (isset($supplier)) {
|
||||
$asset->supplier_id = $supplier->id;
|
||||
}
|
||||
if ($this->item["notes"]) {
|
||||
$asset->notes = $this->item["notes"];
|
||||
}
|
||||
if (!empty($asset_image)) {
|
||||
$asset->image = $asset_image;
|
||||
}
|
||||
if (!$editingAsset) {
|
||||
$this->assets->add($asset);
|
||||
}
|
||||
if (!$this->testRun) {
|
||||
if ($asset->save()) {
|
||||
$asset->logCreate('Imported using csv importer');
|
||||
$this->log('Asset ' . $this->item["item_name"] . ' with serial number ' . $asset_serial . ' was created');
|
||||
} else {
|
||||
$this->jsonError($asset, 'Asset', $asset->getErrors());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
105
app/Importer/ConsumableImporter.php
Normal file
105
app/Importer/ConsumableImporter.php
Normal file
|
@ -0,0 +1,105 @@
|
|||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: parallelgrapefruit
|
||||
* Date: 12/24/16
|
||||
* Time: 1:03 PM
|
||||
*/
|
||||
|
||||
namespace App\Importer;
|
||||
|
||||
|
||||
use App\Helpers\Helper;
|
||||
use App\Models\Consumable;
|
||||
|
||||
class ConsumableImporter extends ItemImporter
|
||||
{
|
||||
protected $consumables;
|
||||
function __construct($filename, $logCallback, $progressCallback, $errorCallback, $testRun = false, $user_id = -1, $updating = false, $usernameFormat = null)
|
||||
{
|
||||
parent::__construct($filename, $logCallback, $progressCallback, $errorCallback, $testRun, $user_id, $updating, $usernameFormat);
|
||||
$this->consumables = Consumable::all();
|
||||
}
|
||||
|
||||
protected function handle($row)
|
||||
{
|
||||
parent::handle($row); // TODO: Change the autogenerated stub
|
||||
$this->createConsumableIfNotExists();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a consumable if a duplicate does not exist
|
||||
*
|
||||
* @author Daniel Melzter
|
||||
* @since 3.0
|
||||
*/
|
||||
public function createConsumableIfNotExists()
|
||||
{
|
||||
$consumable = null;
|
||||
$editingConsumable = false;
|
||||
$this->log("Creating Consumable");
|
||||
$consumable = $this->consumables->search(function ($key) {
|
||||
return strcasecmp($key->name, $this->item['item_name']) == 0;
|
||||
});
|
||||
if($consumable) {
|
||||
$editingConsumable = true;
|
||||
if (!$this->updating) {
|
||||
$this->log('A matching Consumable ' . $this->item["item_name"] . ' already exists. ');
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
$this->log("No matching consumable, creating one");
|
||||
$consumable = new Consumable();
|
||||
}
|
||||
if (!$editingConsumable) {
|
||||
$consumable->name = $this->item["item_name"];
|
||||
}
|
||||
if (!empty($this->item["purchase_date"])) {
|
||||
$consumable->purchase_date = $this->item["purchase_date"];
|
||||
} else {
|
||||
$consumable->purchase_date = null;
|
||||
}
|
||||
|
||||
if (!empty($this->item["purchase_cost"])) {
|
||||
$consumable->purchase_cost = Helper::ParseFloat($this->item["purchase_cost"]);
|
||||
}
|
||||
if (isset($this->item["location"])) {
|
||||
$consumable->location_id = $this->item["location"]->id;
|
||||
}
|
||||
$consumable->user_id = $this->user_id;
|
||||
if (isset($this->item["company"])) {
|
||||
$consumable->company_id = $this->item["company"]->id;
|
||||
}
|
||||
if (!empty($this->item["order_number"])) {
|
||||
$consumable->order_number = $this->item["order_number"];
|
||||
}
|
||||
if (isset($this->item["category"])) {
|
||||
$consumable->category_id = $this->item["category"]->id;
|
||||
}
|
||||
// TODO:Implement
|
||||
//$consumable->notes= e($this->item_notes);
|
||||
if (!empty($this->item["requestable"])) {
|
||||
$consumable->requestable = filter_var($this->item["requestable"], FILTER_VALIDATE_BOOLEAN);
|
||||
}
|
||||
|
||||
if (!empty($this->item["quantity"])) {
|
||||
if ($this->item["quantity"] > -1) {
|
||||
$consumable->qty = $this->item["quantity"];
|
||||
} else {
|
||||
$consumable->qty = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$this->testRun) {
|
||||
if ($consumable->save()) {
|
||||
$consumable->logCreate('Imported using CSV Importer');
|
||||
$this->log("Consumable " . $this->item["item_name"] . ' was created');
|
||||
|
||||
} else {
|
||||
$this->jsonError($consumable, 'Consumable', $consumable->getErrors());
|
||||
}
|
||||
} else {
|
||||
$this->log('TEST RUN - Consumable ' . $this->item['item_name'] . ' not created');
|
||||
}
|
||||
}
|
||||
}
|
285
app/Importer/Importer.php
Normal file
285
app/Importer/Importer.php
Normal file
|
@ -0,0 +1,285 @@
|
|||
<?php
|
||||
namespace App\Importer;
|
||||
|
||||
|
||||
use App\Models\AssetModel;
|
||||
use App\Models\Category;
|
||||
use App\Models\Company;
|
||||
use App\Models\CustomField;
|
||||
use App\Models\Location;
|
||||
use App\Models\Manufacturer;
|
||||
use App\Models\Setting;
|
||||
use App\Models\Statuslabel;
|
||||
use App\Models\Supplier;
|
||||
use App\Models\User;
|
||||
use ForceUTF8\Encoding;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use League\Csv\Reader;
|
||||
|
||||
abstract class Importer
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $filename;
|
||||
private $csv;
|
||||
/**
|
||||
* Should we persist to database?
|
||||
* @var bool
|
||||
*/
|
||||
protected $testRun;
|
||||
/**
|
||||
* Id of User performing import
|
||||
* @var
|
||||
*/
|
||||
protected $user_id;
|
||||
/**
|
||||
* Are we updating items in the import
|
||||
* @var bool
|
||||
*/
|
||||
protected $updating;
|
||||
/**
|
||||
* @var callable
|
||||
*/
|
||||
protected $logCallback;
|
||||
protected $tempPassword;
|
||||
/**
|
||||
* @var callable
|
||||
*/
|
||||
protected $progressCallback;
|
||||
/**
|
||||
* @var null
|
||||
*/
|
||||
protected $usernameFormat;
|
||||
/**
|
||||
* @var callable
|
||||
*/
|
||||
protected $errorCallback;
|
||||
|
||||
/**
|
||||
* ObjectImporter constructor.
|
||||
* @param string $filename
|
||||
* @param callable $logCallback
|
||||
* @param callable $progressCallback
|
||||
* @param callable $errorCallback
|
||||
* @param bool $testRun
|
||||
* @param int $user_id
|
||||
* @param bool $updating
|
||||
* @param null $usernameFormat
|
||||
*/
|
||||
function __construct(string $filename,
|
||||
$logCallback,
|
||||
$progressCallback,
|
||||
$errorCallback,
|
||||
$testRun = false,
|
||||
$user_id = -1,
|
||||
$updating = false,
|
||||
$usernameFormat = null)
|
||||
{
|
||||
$this->filename = $filename;
|
||||
$this->csv = Reader::createFromPath($filename);
|
||||
$this->csv->setNewLine('\r\n');
|
||||
if (! ini_get("auto_detect_line_endings")) {
|
||||
ini_set("auto_detect_line_endings", '1');
|
||||
}
|
||||
$this->testRun = $testRun;
|
||||
if($user_id == -1) {
|
||||
$user_id = Auth::id();
|
||||
}
|
||||
$this->user_id = $user_id;
|
||||
$this->updating = $updating;
|
||||
$this->logCallback = $logCallback;
|
||||
$this->tempPassword = substr(str_shuffle("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), 0, 20);
|
||||
$this->progressCallback = $progressCallback;
|
||||
$this->usernameFormat = $usernameFormat;
|
||||
$this->errorCallback = $errorCallback;
|
||||
}
|
||||
// Cached Values for import lookups
|
||||
protected $locations;
|
||||
protected $categories;
|
||||
protected $manufacturers;
|
||||
protected $asset_models;
|
||||
protected $companies;
|
||||
protected $status_labels;
|
||||
protected $suppliers;
|
||||
protected $assets;
|
||||
protected $accessories;
|
||||
protected $consumables;
|
||||
protected $customFields;
|
||||
|
||||
public function import()
|
||||
{
|
||||
// dd($this->csv->fetchAssoc());
|
||||
$results = $this->normalizeInputArray($this->csv->fetchAssoc());
|
||||
$this->initializeLookupArrays();
|
||||
DB::transaction(function () use (&$results) {
|
||||
Model::unguard();
|
||||
$resultsCount = sizeof($results);
|
||||
foreach ($results as $row) {
|
||||
|
||||
// Let's just map some of these entries to more user friendly words
|
||||
|
||||
// Fetch general items here, fetch item type specific items in respective methods
|
||||
/** @var Asset, License, Accessory, or Consumable $item_type */
|
||||
$this->handle($row);
|
||||
call_user_func($this->progressCallback, $resultsCount);
|
||||
|
||||
$this->log('------------- Action Summary ----------------');
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
abstract protected function handle($row);
|
||||
|
||||
/**
|
||||
* @param $results
|
||||
* @return array
|
||||
*/
|
||||
public function normalizeInputArray($results): array
|
||||
{
|
||||
$newArray = [];
|
||||
|
||||
foreach ($results as $index => $arrayToNormalize) {
|
||||
$newArray[$index] = array_change_key_case($arrayToNormalize);
|
||||
}
|
||||
return $newArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load Cached versions of all used methods.
|
||||
*/
|
||||
public function initializeLookupArrays()
|
||||
{
|
||||
$this->locations = Location::All(['name', 'id']);
|
||||
$this->categories = Category::All(['name', 'category_type', 'id']);
|
||||
$this->manufacturers = Manufacturer::All(['name', 'id']);
|
||||
$this->asset_models = AssetModel::All(['name', 'model_number', 'category_id', 'manufacturer_id', 'id']);
|
||||
$this->companies = Company::All(['name', 'id']);
|
||||
$this->status_labels = Statuslabel::All(['name', 'id']);
|
||||
$this->suppliers = Supplier::All(['name', 'id']);
|
||||
$this->customFields = CustomField::All(['name']);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if the given key exists in the array, and trim excess white space before returning it
|
||||
*
|
||||
* @author Daniel Melzter
|
||||
* @since 3.0
|
||||
* @param $array array
|
||||
* @param $key string
|
||||
* @param $default string
|
||||
* @return string
|
||||
*/
|
||||
public function array_smart_fetch(array $array, $key, $default = '')
|
||||
{
|
||||
return array_key_exists(trim($key), $array) ? e(Encoding::fixUTF8(trim($array[ $key ]))) : $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Figure out the fieldname of the custom field
|
||||
*
|
||||
* @author A. Gianotto <snipe@snipe.net>
|
||||
* @since 3.0
|
||||
* @param $array array
|
||||
* @return string
|
||||
*/
|
||||
public function array_smart_custom_field_fetch(array $array, $key)
|
||||
{
|
||||
$index_name = strtolower($key->name);
|
||||
return array_key_exists($index_name, $array) ? e(trim($array[$index_name])) : '';
|
||||
}
|
||||
|
||||
protected function log($string) {
|
||||
call_user_func($this->logCallback, $string);
|
||||
}
|
||||
|
||||
protected function jsonError($item, $field, $errorString) {
|
||||
call_user_func($this->errorCallback, $item, $field, $errorString);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the user matching given data, or creates a new one if there is no match
|
||||
*
|
||||
* @author Daniel Melzter
|
||||
* @since 3.0
|
||||
* @param $row array
|
||||
* @return User Model w/ matching name
|
||||
* @internal param string $user_username Username extracted from CSV
|
||||
* @internal param string $user_email Email extracted from CSV
|
||||
* @internal param string $first_name
|
||||
* @internal param string $last_name
|
||||
*/
|
||||
protected function createOrFetchUser($row)
|
||||
{
|
||||
$user_name = $this->array_smart_fetch($row, "name");
|
||||
$user_email = $this->array_smart_fetch($row, "email");
|
||||
$user_username = $this->array_smart_fetch($row, "username");
|
||||
$first_name = '';
|
||||
$last_name = '';
|
||||
// A number was given instead of a name
|
||||
if (is_numeric($user_name)) {
|
||||
$this->log('User '.$user_name.' is not a name - assume this user already exists');
|
||||
$user_username = '';
|
||||
// No name was given
|
||||
} elseif (empty($user_name)) {
|
||||
$this->log('No user data provided - skipping user creation, just adding asset');
|
||||
//$user_username = '';
|
||||
} else {
|
||||
$user_email_array = User::generateFormattedNameFromFullName(Setting::getSettings()->email_format, $user_name);
|
||||
$first_name = $user_email_array['first_name'];
|
||||
$last_name = $user_email_array['last_name'];
|
||||
|
||||
if ($user_email=='') {
|
||||
if (Setting::getSettings()->email_domain) {
|
||||
$user_email = str_slug($user_email_array['username']).'@'.Setting::getSettings()->email_domain;
|
||||
}
|
||||
}
|
||||
|
||||
if ($user_username=='') {
|
||||
if ($this->usernameFormat =='email') {
|
||||
$user_username = $user_email;
|
||||
} else {
|
||||
$user_name_array = User::generateFormattedNameFromFullName(Setting::getSettings()->username_format, $user_name);
|
||||
$user_username = $user_name_array['username'];
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->log("--- User Data ---");
|
||||
$this->log('Full Name: ' . $user_name);
|
||||
$this->log('First Name: ' . $first_name);
|
||||
$this->log('Last Name: ' . $last_name);
|
||||
$this->log('Username: ' . $user_username);
|
||||
$this->log('Email: ' . $user_email);
|
||||
$this->log('--- End User Data ---');
|
||||
|
||||
$user = new User;
|
||||
if ($this->testRun) {
|
||||
return $user;
|
||||
}
|
||||
if (!empty($user_username)) {
|
||||
if ($user = User::MatchEmailOrUsername($user_username, $user_email)
|
||||
->whereNotNull('username')->first()) {
|
||||
$this->log('User '.$user_username.' already exists');
|
||||
} elseif (( $first_name != '') && ($last_name != '') && ($user_username != '')) {
|
||||
$user = new User;
|
||||
$user->first_name = $first_name;
|
||||
$user->last_name = $last_name;
|
||||
$user->username = $user_username;
|
||||
$user->email = $user_email;
|
||||
$user->activated = 1;
|
||||
$user->password = $this->tempPassword;
|
||||
|
||||
if ($user->save()) {
|
||||
$this->log('User '.$first_name.' created');
|
||||
} else {
|
||||
$this->jsonError($user,'User "' . $first_name . '"', $user->getErrors());
|
||||
}
|
||||
}
|
||||
}
|
||||
return $user;
|
||||
}
|
||||
}
|
399
app/Importer/ItemImporter.php
Normal file
399
app/Importer/ItemImporter.php
Normal file
|
@ -0,0 +1,399 @@
|
|||
<?php
|
||||
|
||||
namespace App\Importer;
|
||||
|
||||
|
||||
use App\Models\AssetModel;
|
||||
use App\Models\Category;
|
||||
use App\Models\Company;
|
||||
use App\Models\Location;
|
||||
use App\Models\Manufacturer;
|
||||
use App\Models\Statuslabel;
|
||||
use App\Models\Supplier;
|
||||
|
||||
class ItemImporter extends Importer
|
||||
{
|
||||
protected $item;
|
||||
function __construct($filename, $logCallback, $progressCallback, $errorCallback, $testRun = false, $user_id = -1, $updating = false, $usernameFormat = null)
|
||||
{
|
||||
parent::__construct($filename, $logCallback, $progressCallback, $errorCallback, $testRun, $user_id, $updating, $usernameFormat);
|
||||
}
|
||||
|
||||
protected function handle($row)
|
||||
{
|
||||
$item_category = $this->array_smart_fetch($row, "category");
|
||||
$item_company_name = $this->array_smart_fetch($row, "company");
|
||||
$item_location = $this->array_smart_fetch($row, "location");
|
||||
$item_manufacturer = $this->array_smart_fetch($row, "manufacturer");
|
||||
$item_status_name = $this->array_smart_fetch($row, "status");
|
||||
$this->item["item_name"] = $this->array_smart_fetch($row, "item name");
|
||||
if ($this->array_smart_fetch($row, "purchase date")!='') {
|
||||
$this->item["purchase_date"] = date("Y-m-d 00:00:01", strtotime($this->array_smart_fetch($row, "purchase date")));
|
||||
} else {
|
||||
$this->item["purchase_date"] = null;
|
||||
}
|
||||
|
||||
$this->item["purchase_cost"] = $this->array_smart_fetch($row, "purchase cost");
|
||||
$this->item["order_number"] = $this->array_smart_fetch($row, "order number");
|
||||
$this->item["notes"] = $this->array_smart_fetch($row, "notes");
|
||||
$this->item["quantity"] = $this->array_smart_fetch($row, "quantity");
|
||||
$this->item["requestable"] = $this->array_smart_fetch($row, "requestable");
|
||||
$this->item["asset_tag"] = $this->array_smart_fetch($row, "asset tag");
|
||||
|
||||
$this->item["user"] = $this->createOrFetchUser($row);
|
||||
|
||||
if (!($this->updating && empty($item_location))) {
|
||||
$this->item["location"] = $this->createOrFetchLocation($item_location);
|
||||
}
|
||||
if (!($this->updating && empty($item_category))) {
|
||||
$this->item["category"] = $this->createOrFetchCategory($item_category);
|
||||
}
|
||||
if (!($this->updating && empty($item_manufacturer))) {
|
||||
$this->item["manufacturer"] = $this->createOrFetchManufacturer($item_manufacturer);
|
||||
}
|
||||
if (!($this->updating && empty($item_company_name))) {
|
||||
$this->item["company"] = $this->createOrFetchCompany($item_company_name);
|
||||
}
|
||||
|
||||
if (!($this->updating && empty($item_status_name))) {
|
||||
$this->item["status_label"] = $this->createOrFetchStatusLabel($item_status_name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Select the asset model if it exists, otherwise create it.
|
||||
*
|
||||
* @author Daniel Melzter
|
||||
* @since 3.0
|
||||
* @param array
|
||||
* @param $category Category
|
||||
* @param $manufacturer Manufacturer
|
||||
* @return AssetModel
|
||||
* @internal param $asset_modelno string
|
||||
*/
|
||||
public function createOrFetchAssetModel(array $row, $category, $manufacturer)
|
||||
{
|
||||
$asset_model_name = $this->array_smart_fetch($row, "model name");
|
||||
$asset_modelNumber = $this->array_smart_fetch($row, "model number");
|
||||
if ((empty($asset_model_name)) && (!empty($asset_modelNumber))) {
|
||||
$asset_model_name = $asset_modelNumber;
|
||||
} elseif ((empty($asset_model_name)) && (empty($asset_modelNumber))) {
|
||||
$asset_model_name ='Unknown';
|
||||
}
|
||||
$this->log('Model Name: ' . $asset_model_name);
|
||||
$this->log('Model No: ' . $asset_modelNumber);
|
||||
|
||||
$asset_model = null;
|
||||
$editingModel = $this->updating;
|
||||
$asset_model = $this->asset_models->search(function ($key) use ($asset_model_name, $asset_modelNumber) {
|
||||
return strcasecmp($key->name, $asset_model_name) ==0
|
||||
&& $key->model_number == $asset_modelNumber;
|
||||
});
|
||||
// We need strict compare here because the index returned above can be 0.
|
||||
// This casts to false and causes false positives
|
||||
if(($asset_model !== false) && !$editingModel) {
|
||||
return $this->asset_models[$asset_model];
|
||||
} else {
|
||||
$this->log("No Matching Model, Creating a new one");
|
||||
$asset_model = new AssetModel();
|
||||
}
|
||||
if (($editingModel && ($asset_model_name != "Unknown"))
|
||||
|| (!$editingModel)) {
|
||||
$asset_model->name = $asset_model_name;
|
||||
}
|
||||
isset($manufacturer) && $manufacturer->exists() && $asset_model->manufacturer_id = $manufacturer->id;
|
||||
isset($asset_modelNumber) && $asset_model->model_number = $asset_modelNumber;
|
||||
if (isset($category) && $category->exists()) {
|
||||
$asset_model->category_id = $category->id;
|
||||
}
|
||||
$asset_model->user_id = $this->user_id;
|
||||
|
||||
if (!$editingModel) {
|
||||
$this->asset_models->add($asset_model);
|
||||
}
|
||||
if (!$this->testRun) {
|
||||
if ($asset_model->save()) {
|
||||
$this->log('Asset Model ' . $asset_model_name . ' with model number ' . $asset_modelNumber . ' was created');
|
||||
return $asset_model;
|
||||
} else {
|
||||
$this->jsonError($asset_model,'Asset Model "' . $asset_model_name . '"', $asset_model->getErrors());
|
||||
$this->log('Asset Model "' . $asset_model_name . '"' . $asset_model->getErrors());
|
||||
return $asset_model;
|
||||
}
|
||||
} else {
|
||||
$this->asset_models->add($asset_model);
|
||||
return $asset_model;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a category with the same name and item type in the database, otherwise creates it
|
||||
*
|
||||
* @author Daniel Melzter
|
||||
* @since 3.0
|
||||
* @param $asset_category string
|
||||
* @return Category
|
||||
* @internal param string $item_type
|
||||
*/
|
||||
public function createOrFetchCategory($asset_category)
|
||||
{
|
||||
// Magic to transform "AssetImporter" to "asset" or similar.
|
||||
$classname = get_class($this);
|
||||
$item_type = strtolower(substr($classname, 0, strpos($classname, 'Importer')));
|
||||
if (empty($asset_category)) {
|
||||
$asset_category = 'Unnamed Category';
|
||||
}
|
||||
$category = $this->categories->search(function ($key) use ($asset_category, $item_type) {
|
||||
return (strcasecmp($key->name, $asset_category) == 0)
|
||||
&& $key->category_type === $item_type;
|
||||
});
|
||||
// We need strict compare here because the index returned above can be 0.
|
||||
// This casts to false and causes false positives
|
||||
if ($category !== false) {
|
||||
return $this->categories[$category];
|
||||
}
|
||||
|
||||
$category = new Category();
|
||||
|
||||
$category->name = $asset_category;
|
||||
$category->category_type = $item_type;
|
||||
$category->user_id = $this->user_id;
|
||||
|
||||
if (!$this->testRun) {
|
||||
if ($category->save()) {
|
||||
$this->categories->add($category);
|
||||
$this->log('Category ' . $asset_category . ' was created');
|
||||
return $category;
|
||||
} else {
|
||||
$this->jsonError($category, 'Category "'. $asset_category. '"', $category->getErrors());
|
||||
return $category;
|
||||
}
|
||||
} else {
|
||||
$this->categories->add($category);
|
||||
return $category;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch an existing company, or create new if it doesn't exist
|
||||
*
|
||||
* @author Daniel Melzter
|
||||
* @since 3.0
|
||||
* @param $asset_company_name string
|
||||
* @return Company
|
||||
*/
|
||||
public function createOrFetchCompany($asset_company_name)
|
||||
{
|
||||
$company = $this->companies->search(function ($key) use($asset_company_name) {
|
||||
return strcasecmp($key->name, $asset_company_name) == 0;
|
||||
});
|
||||
// We need strict compare here because the index returned above can be 0.
|
||||
// This casts to false and causes false positives
|
||||
if($company !== false) {
|
||||
$this->log('A matching Company ' . $asset_company_name . ' already exists');
|
||||
return $this->companies[$company];
|
||||
}
|
||||
$company = new Company();
|
||||
$company->name = $asset_company_name;
|
||||
|
||||
if (!$this->testRun) {
|
||||
if ($company->save()) {
|
||||
$this->companies->add($company);
|
||||
$this->log('Company ' . $asset_company_name . ' was created');
|
||||
return $company;
|
||||
} else {
|
||||
$this->log('Company', $company->getErrors());
|
||||
}
|
||||
} else {
|
||||
$this->companies->add($company);
|
||||
return $company;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the existing status label or create new if it doesn't exist.
|
||||
*
|
||||
* @author Daniel Melzter
|
||||
* @since 3.0
|
||||
* @param string $asset_statuslabel_name
|
||||
* @return Statuslabel
|
||||
*/
|
||||
public function createOrFetchStatusLabel($asset_statuslabel_name)
|
||||
{
|
||||
if (empty($asset_statuslabel_name)) {
|
||||
return null;
|
||||
}
|
||||
$status = $this->status_labels->search(function ($key) use($asset_statuslabel_name) {
|
||||
return strcasecmp($key->name, $asset_statuslabel_name) == 0;
|
||||
});
|
||||
// We need strict compare here because the index returned above can be 0.
|
||||
// This casts to false and causes false positives
|
||||
if ($status !== false) {
|
||||
$this->log('A matching Status ' . $asset_statuslabel_name . ' already exists');
|
||||
return $this->status_labels[$status];
|
||||
}
|
||||
$this->log("Creating a new status");
|
||||
$status = new Statuslabel();
|
||||
$status->name = $asset_statuslabel_name;
|
||||
|
||||
$status->deployable = 1;
|
||||
$status->pending = 0;
|
||||
$status->archived = 0;
|
||||
|
||||
if (!$this->testRun) {
|
||||
if ($status->save()) {
|
||||
$this->status_labels->add($status);
|
||||
$this->log('Status ' . $asset_statuslabel_name . ' was created');
|
||||
return $status;
|
||||
} else {
|
||||
$this->jsonError($status,'Status "'. $asset_statuslabel_name . '"', $status->getErrors());
|
||||
return $status;
|
||||
}
|
||||
} else {
|
||||
$this->status_labels->add($status);
|
||||
return $status;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a manufacturer with matching name, otherwise create it.
|
||||
*
|
||||
* @author Daniel Melzter
|
||||
* @since 3.0
|
||||
* @param $item_manufacturer string
|
||||
* @return Manufacturer
|
||||
*/
|
||||
|
||||
public function createOrFetchManufacturer($item_manufacturer)
|
||||
{
|
||||
|
||||
if (empty($item_manufacturer)) {
|
||||
$item_manufacturer='Unknown';
|
||||
}
|
||||
$manufacturer = $this->manufacturers->search(function ($key) use($item_manufacturer) {
|
||||
return strcasecmp($key->name, $item_manufacturer) == 0;
|
||||
});
|
||||
// We need strict compare here because the index returned above can be 0.
|
||||
// This casts to false and causes false positives
|
||||
if ($manufacturer !== false) {
|
||||
$this->log('Manufacturer ' . $item_manufacturer . ' already exists') ;
|
||||
return $this->manufacturers[$manufacturer];
|
||||
}
|
||||
|
||||
//Otherwise create a manufacturer.
|
||||
$manufacturer = new Manufacturer();
|
||||
$manufacturer->name = $item_manufacturer;
|
||||
$manufacturer->user_id = $this->user_id;
|
||||
|
||||
if (!$this->testRun) {
|
||||
if ($manufacturer->save()) {
|
||||
$this->manufacturers->add($manufacturer);
|
||||
$this->log('Manufacturer ' . $manufacturer->name . ' was created');
|
||||
return $manufacturer;
|
||||
} else {
|
||||
$this->jsonError($manufacturer, 'Manufacturer "'. $manufacturer->name . '"', $manufacturer->getErrors());
|
||||
return $manufacturer;
|
||||
}
|
||||
|
||||
} else {
|
||||
$this->manufacturers->add($manufacturer);
|
||||
return $manufacturer;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the DB to see if a location with the same name exists, otherwise create it
|
||||
*
|
||||
* @author Daniel Melzter
|
||||
* @since 3.0
|
||||
* @param $asset_location string
|
||||
* @return Location|null
|
||||
*/
|
||||
public function createOrFetchLocation($asset_location)
|
||||
{
|
||||
if (empty($asset_location)) {
|
||||
$this->log('No location given, so none created.');
|
||||
return null;
|
||||
}
|
||||
$location = $this->locations->search(function ($key) use($asset_location) {
|
||||
return strcasecmp($key->name, $asset_location) == 0;
|
||||
});
|
||||
// We need strict compare here because the index returned above can be 0.
|
||||
// This casts to false and causes false positives
|
||||
if ($location !== false) {
|
||||
$this->log('Location ' . $asset_location . ' already exists');
|
||||
return $this->locations[$location];
|
||||
}
|
||||
// No matching locations in the collection, create a new one.
|
||||
$location = new Location();
|
||||
|
||||
|
||||
$location->name = $asset_location;
|
||||
$location->address = '';
|
||||
$location->city = '';
|
||||
$location->state = '';
|
||||
$location->country = '';
|
||||
$location->user_id = $this->user_id;
|
||||
|
||||
if (!$this->testRun) {
|
||||
if ($location->save()) {
|
||||
$this->locations->add($location);
|
||||
$this->log('Location ' . $asset_location . ' was created');
|
||||
return $location;
|
||||
} else {
|
||||
$this->log('Location', $location->getErrors()) ;
|
||||
return $location;
|
||||
}
|
||||
} else {
|
||||
$this->locations->add($location);
|
||||
return $location;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch an existing supplier or create new if it doesn't exist
|
||||
*
|
||||
* @author Daniel Melzter
|
||||
* @since 3.0
|
||||
* @param $row array
|
||||
* @return Supplier
|
||||
*/
|
||||
public function createOrFetchSupplier($item_supplier)
|
||||
{
|
||||
if (empty($item_supplier)) {
|
||||
$item_supplier='Unknown';
|
||||
}
|
||||
|
||||
$supplier = $this->suppliers->search(function ($key) use($item_supplier) {
|
||||
return strcasecmp($key->name, $item_supplier) == 0;
|
||||
});
|
||||
// We need strict compare here because the index returned above can be 0.
|
||||
// This casts to false and causes false positives
|
||||
if ($supplier !== false) {
|
||||
$this->log('Supplier ' . $item_supplier . ' already exists');
|
||||
return $this->suppliers[$supplier];
|
||||
}
|
||||
|
||||
$supplier = new Supplier();
|
||||
$supplier->name = $item_supplier;
|
||||
$supplier->user_id = $this->user_id;
|
||||
|
||||
if (!$this->testRun) {
|
||||
if ($supplier->save()) {
|
||||
$this->suppliers->add($supplier);
|
||||
$this->log('Supplier ' . $item_supplier . ' was created');
|
||||
return $supplier;
|
||||
} else {
|
||||
$this->log('Supplier', $supplier->getErrors());
|
||||
return $supplier;
|
||||
}
|
||||
} else {
|
||||
$this->suppliers->add($supplier);
|
||||
return $supplier;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
Loading…
Reference in a new issue