diff --git a/app/Console/Commands/AssetImportCommand.php b/app/Console/Commands/AssetImportCommand.php deleted file mode 100644 index 851a3c216f..0000000000 --- a/app/Console/Commands/AssetImportCommand.php +++ /dev/null @@ -1,463 +0,0 @@ -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), - ); - } -} diff --git a/app/Console/Commands/ObjectImportCommand.php b/app/Console/Commands/ObjectImportCommand.php index 4064a01420..3ad3dc6856 100644 --- a/app/Console/Commands/ObjectImportCommand.php +++ b/app/Console/Commands/ObjectImportCommand.php @@ -2,6 +2,10 @@ namespace App\Console\Commands; use App\Helpers\Helper; +use App\Importer\AccessoryImporter; +use App\Importer\AssetImporter; +use App\Importer\ConsumableImporter; +use App\Importer\Importer; use App\Models\Accessory; use App\Models\Asset; use App\Models\AssetModel; @@ -55,7 +59,7 @@ class ObjectImportCommand extends Command { parent::__construct(); } - + private $bar; /** * Execute the console command. * @@ -64,203 +68,86 @@ class ObjectImportCommand extends Command public function fire() { $filename = $this->argument('filename'); - - $tmp_password = substr(str_shuffle("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), 0, 20); - $password = bcrypt($tmp_password); - - $this->updating = $this->option('update'); - if (!$this->option('web-importer')) { - $logFile = $this->option('logfile'); - \Log::useFiles($logFile); - if ($this->option('testrun')) { - $this->comment('====== TEST ONLY Asset Import for '.$filename.' ===='); - $this->comment('============== NO DATA WILL BE WRITTEN =============='); - } else { - - $this->comment('======= Importing Assets from '.$filename.' ========='); - } - } - - if (! ini_get("auto_detect_line_endings")) { - ini_set("auto_detect_line_endings", '1'); - } - - $csv = Reader::createFromPath($this->argument('filename')); - $csv->setNewline("\r\n"); - $results = $csv->fetchAssoc(); - $newarray = null; - - foreach ($results as $index => $arraytoNormalize) { - $internalnewarray = array_change_key_case($arraytoNormalize); - $newarray[$index] = $internalnewarray; - } - - - - $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']); + $importerClass = Importer::class; switch (strtolower($this->option('item-type'))) { case "asset": - $this->assets = Asset::all(); + $importerClass = AssetImporter::class; break; case "accessory": - $this->accessories = Accessory::All(); + $importerClass = AccessoryImporter::class; break; case "component": - $this->components = Component::All(); + die("This is not implemented yet"); + $importerClass = ComponentImporter::class; break; case "consumable": - $this->consumables = Consumable::All(); + $importerClass = ConsumableImporter::class; break; } - $this->customfields = CustomField::All(['name']); - $bar = null; - - if (!$this->option('web-importer')) { - $bar = $this->output->createProgressBar(count($newarray)); + $importer = new $importerClass( + $filename, + [$this, 'log'], + [$this, 'progress'], + [$this, 'errorCallback'], + $this->option('testrun'), + $this->option('user_id'), + $this->option('update'), + $this->option('username_format') + ); + $logFile = $this->option('logfile'); + \Log::useFiles($logFile); + if ($this->option('testrun')) { + $this->comment('====== TEST ONLY Asset Import for '.$filename.' ===='); + $this->comment('============== NO DATA WILL BE WRITTEN =============='); + } else { + $this->comment('======= Importing Assets from '.$filename.' ========='); } - // Loop through the records - DB::transaction(function () use (&$newarray, $bar, $password) { - Model::unguard(); - $item_type = strtolower($this->option('item-type')); + $importer->import(); + $this->bar = null; - - foreach ($newarray 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 */ - - $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"); - - $item["item_name"] = $this->array_smart_fetch($row, "item name"); - if ($this->array_smart_fetch($row, "purchase date")!='') { - $item["purchase_date"] = date("Y-m-d 00:00:01", strtotime($this->array_smart_fetch($row, "purchase date"))); - } else { - $item["purchase_date"] = null; - } - - $item["purchase_cost"] = $this->array_smart_fetch($row, "purchase cost"); - $item["order_number"] = $this->array_smart_fetch($row, "order number"); - $item["notes"] = $this->array_smart_fetch($row, "notes"); - $item["quantity"] = $this->array_smart_fetch($row, "quantity"); - $item["requestable"] = $this->array_smart_fetch($row, "requestable"); - $item["asset_tag"] = $this->array_smart_fetch($row, "asset tag"); - - - $this->current_assetId = $item["item_name"]; - if ($item["asset_tag"] != '') { - $this->current_assetId = $item["asset_tag"]; - } - $this->log('Category: ' . $item_category); - $this->log('Location: ' . $item_location); - $this->log('Manufacturer: ' . $item_manufacturer); - $this->log('Purchase Date: ' . $item["purchase_date"]); - $this->log('Purchase Cost: ' . $item["purchase_cost"]); - $this->log('Company Name: ' . $item_company_name); - $this->log('Status: ' . $item_status_name); - - - $item["user"] = $this->createOrFetchUser($row, $password); - - if (!($this->updating && empty($item_location))) { - $item["location"] = $this->createOrFetchLocation($item_location); - } - if (!($this->updating && empty($item_category))) { - $item["category"] = $this->createOrFetchCategory($item_category, $item_type); - } - if (!($this->updating && empty($item_manufacturer))) { - $item["manufacturer"] = $this->createOrFetchManufacturer($item_manufacturer); - } - if (!($this->updating && empty($item_company_name))) { - $item["company"] = $this->createOrFetchCompany($item_company_name); - } - - if (!($this->updating && empty($item_status_name))) { - $item["status_label"] = $this->createOrFetchStatusLabel($item_status_name); - } - - switch ($item_type) { - case "asset": - // ----------------------------- - // CUSTOM FIELDS - // ----------------------------- - // Loop through custom fields in the database and see if we have any matches in the CSV - foreach ($this->customfields as $customfield) { - if ($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, $item); - break; - case "accessory": - $this->createAccessoryIfNotExists($item); - break; - case 'consumable': - $this->createConsumableIfNotExists($item); - break; - } - - if (!$this->option('web-importer')) { - $bar->advance(); - } - $this->log('------------- Action Summary ----------------'); - - } - }); - if (!$this->option('web-importer')) { - $bar->finish(); - } - - - $this->log('====================================='); - if (!$this->option('web-importer')) { - if (!empty($this->errors)) { - $this->comment("The following Errors were encountered."); - foreach ($this->errors as $asset => $error) { - $this->comment('Error: Item: ' . $asset . 'failed validation: ' . json_encode($error)); - } - } else { - $this->comment("All Items imported successfully!"); + if (!empty($this->errors)) { + $this->comment("The following Errors were encountered."); + foreach ($this->errors as $asset => $error) { + $this->comment('Error: Item: ' . $asset . ' failed validation: ' . json_encode($error)); } } else { - if (empty($this->errors)) { - return 0; - } else { - $this->comment(json_encode($this->errors)); //Send a big string to the - return 1; - } + $this->comment("All Items imported successfully!"); } - $this->comment(""); + $this->comment(""); - return 2; + return; + } + + public function errorCallback($item, $field, $errorString) + { + $this->errors[$item->name][$field] = $errorString; + } + public function progress($count) + { + if(!$this->bar) { + $this->bar = $this->output->createProgressBar($count); + } + static $index =0; + $index++; + if($index < $count) { + $this->bar->advance(); + } else { + $this->bar->finish(); + } } // Tracks the current item for error messages - private $current_assetId; private $updating; // An array of errors encountered while parsing private $errors; - public function jsonError($field, $errorString) - { - $this->errors[$this->current_assetId][$field] = $errorString; - if ($this->option('verbose')) { - parent::error($field . $errorString); - } - } +// public function jsonError($field, $errorString) +// { +// $this->errors[$this->current_assetId][$field] = $errorString; +// if ($this->option('verbose')) { +// parent::error($field . $errorString); +// } +// } /** * Log a message to file, configurable by the --log-file parameter. @@ -271,11 +158,8 @@ class ObjectImportCommand extends Command * @param string $string * @param string $level */ - private function log($string, $level = 'info') + public function log($string, $level = 'info') { - if ($this->option('web-importer')) { - return; - } if ($level === 'warning') { \Log::warning($string); $this->comment($string); @@ -286,792 +170,6 @@ class ObjectImportCommand extends Command } } } - - /** - * 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 - * @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])) : ''; - } - - - - private $asset_models; - /** - * 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 Model - * @internal param $asset_modelno string - */ - public function createOrFetchAssetModel(array $row, $category, $manufacturer) - { - - $asset_model_name = $this->array_smart_fetch($row, "model name"); - $asset_modelno = $this->array_smart_fetch($row, "model number"); - if ((empty($asset_model_name)) && (!empty($asset_modelno))) { - $asset_model_name = $asset_modelno; - } elseif ((empty($asset_model_name)) && (empty($asset_modelno))) { - $asset_model_name ='Unknown'; - } - if (empty($asset_modelno)) { - $asset_modelno=''; - } - $this->log('Model Name: ' . $asset_model_name); - $this->log('Model No: ' . $asset_modelno); - - $asset_model = null; - $editingModel = false; - foreach ($this->asset_models as $tempmodel) { - if (strcasecmp($tempmodel->name, $asset_model_name) == 0 - && $tempmodel->model_number == $asset_modelno) { - $this->log('A matching model ' . $asset_model_name . ' already exists'); - if (!$this->option('update')) { - return $tempmodel; - } - $this->log('Updating matching model with new values'); - $editingModel = true; - $asset_model = $tempmodel; - } - } - if (is_null($asset_model)) { - $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_modelno) && $asset_model->model_number = $asset_modelno; - if (isset($category) && $category->exists) { - $asset_model->category_id = $category->id; - } - $asset_model->user_id = $this->option('user_id'); - - if (!$editingModel) { - $this->asset_models->add($asset_model); - } - if (!$this->option('testrun')) { - if ($asset_model->save()) { - $this->log('Asset Model ' . $asset_model_name . ' with model number ' . $asset_modelno . ' was created'); - return $asset_model; - } else { - $this->jsonError('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; - } - - } - - private $categories; - - /** - * 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 - * @param $item_type string - * @return Category - */ - public function createOrFetchCategory($asset_category, $item_type) - { - if (empty($asset_category)) { - $asset_category = 'Unnamed Category'; - } - - foreach ($this->categories as $tempcategory) { - if ((strcasecmp($tempcategory->name, $asset_category) == 0) && $tempcategory->category_type === $item_type) { - $this->log('Category ' . $asset_category . ' already exists'); - return $tempcategory; - } - } - - $category = new Category(); - - $category->name = $asset_category; - $category->category_type = $item_type; - $category->user_id = $this->option('user_id'); - - - if (!$this->option('testrun')) { - if ($category->save()) { - $this->categories->add($category); - $this->log('Category ' . $asset_category . ' was created'); - return $category; - } else { - $this->jsonError('Category "'. $asset_category. '"', $category->getErrors()); - return $category; - } - } else { - $this->categories->add($category); - return $category; - } - - } - - private $companies; - - /** - * 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) - { - foreach ($this->companies as $tempcompany) { - if (strcasecmp($tempcompany->name, $asset_company_name) == 0) { - $this->log('A matching Company ' . $asset_company_name . ' already exists'); - return $tempcompany; - } - } - - $company = new Company(); - $company->name = $asset_company_name; - - if (!$this->option('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; - } - } - private $status_labels; - /** - * 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 Company - */ - public function createOrFetchStatusLabel($asset_statuslabel_name) - { - if (empty($asset_statuslabel_name)) { - return; - } - foreach ($this->status_labels as $tempstatus) { - if (strcasecmp($tempstatus->name, $asset_statuslabel_name) == 0) { - $this->log('A matching Status ' . $asset_statuslabel_name . ' already exists'); - return $tempstatus; - } - } - $status = new Statuslabel(); - $status->name = $asset_statuslabel_name; - - $status->deployable = 1; - $status->pending = 0; - $status->archived = 0; - - - if (!$this->option('testrun')) { - if ($status->save()) { - $this->status_labels->add($status); - $this->log('Status ' . $asset_statuslabel_name . ' was created'); - return $status; - } else { - $this->jsonError('Status "'. $asset_statuslabel_name . '"', $status->getErrors()); - return $status; - } - } else { - $this->status_labels->add($status); - return $status; - } - } - - private $manufacturers; - - /** - * 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'; - } - - foreach ($this->manufacturers as $tempmanufacturer) { - if (strcasecmp($tempmanufacturer->name, $item_manufacturer) == 0) { - $this->log('Manufacturer ' . $item_manufacturer . ' already exists') ; - return $tempmanufacturer; - } - } - - //Otherwise create a manufacturer. - - $manufacturer = new Manufacturer(); - $manufacturer->name = $item_manufacturer; - $manufacturer->user_id = $this->option('user_id'); - - if (!$this->option('testrun')) { - if ($manufacturer->save()) { - $this->manufacturers->add($manufacturer); - $this->log('Manufacturer ' . $manufacturer->name . ' was created'); - return $manufacturer; - } else { - $this->jsonError('Manufacturer "'. $manufacturer->name . '"', $manufacturer->getErrors()); - return $manufacturer; - } - - } else { - $this->manufacturers->add($manufacturer); - return $manufacturer; - } - } - - /** - * @var - */ - private $locations; - /** - * 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 - */ - public function createOrFetchLocation($asset_location) - { - foreach ($this->locations as $templocation) { - if (strcasecmp($templocation->name, $asset_location) == 0) { - $this->log('Location ' . $asset_location . ' already exists'); - return $templocation; - } - } - // No matching locations in the collection, create a new one. - $location = new Location(); - - if (!empty($asset_location)) { - $location->name = $asset_location; - $location->address = ''; - $location->city = ''; - $location->state = ''; - $location->country = ''; - $location->user_id = $this->option('user_id'); - - if (!$this->option('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; - } - } else { - $this->log('No location given, so none created.'); - return $location; - } - - } - - private $suppliers; - - /** - * 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'; - } - foreach ($this->suppliers as $tempsupplier) { - if (strcasecmp($tempsupplier->name, $item_supplier) == 0) { - $this->log('A matching Supplier ' . $item_supplier . ' already exists'); - return $tempsupplier; - } - } - - $supplier = new Supplier(); - $supplier->name = $item_supplier; - $supplier->user_id = $this->option('user_id'); - - if (!$this->option('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; - } - } - - /** - * 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 - */ - public function createOrFetchUser($row, $password = null) - { - $user_name = $this->array_smart_fetch($row, "name"); - $user_email = $this->array_smart_fetch($row, "email"); - $user_username = $this->array_smart_fetch($row, "username"); - - // 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 = ''; - $first_name = ''; - $last_name = ''; - - // No name was given - } elseif (empty($user_name)) { - $this->log('No user data provided - skipping user creation, just adding asset'); - $first_name = ''; - $last_name = ''; - //$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; - } else { - $user_email = ''; - } - - } - - if ($user_username=='') { - if ($this->option('username_format')=='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 ---'); - - if ($this->option('testrun')) { - return new 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 \App\Models\User; - $user->first_name = $first_name; - $user->last_name = $last_name; - $user->username = $user_username; - $user->email = $user_email; - $user->activated = 1; - $user->password = $password; - - if ($user->save()) { - $this->log('User '.$first_name.' created'); - } else { - $this->jsonError('User "' . $first_name . '"', $user->getErrors()); - } - - } else { - $user = new User; - } - } else { - $user = new User; - } - return $user; - } - - private $assets; - - /** - * Create the asset if it doesn't exist. - * - * @author Daniel Melzter - * @since 3.0 - * @param array $row - * @param array $item - */ - public function createAssetIfNotExists(array $row, array $item) - { - $asset = null; - $editingAsset = false; - foreach ($this->assets as $tempasset) { - if (strcasecmp($tempasset->asset_tag, $item['asset_tag']) == 0) { - $this->log('A matching Asset ' . $item['asset_tag'] . ' already exists'); - if (!$this->option('update')) { - $this->log("Skipping item."); - return; - } - $this->log('Updating matching asset with new values'); - $editingAsset = true; - $asset = $tempasset; - } - } - if (is_null($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($item["category"]) || $item["category"] = new Category(); - isset($item["manufacturer"]) || $item["manufacturer"] = new Manufacturer(); - $asset_model = $this->createOrFetchAssetModel($row, $item["category"], $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: '.$item['asset_tag']); - $this->log('Notes: '.$item["notes"]); - $this->log('Warranty Months: ' . $asset_warranty_months); - - - - if (isset($item["status_label"])) { - $status_id = $item["status_label"]->id; - } else if (!$editingAsset) { - // Assume if we are editing, we already have a status and can ignore. - // FIXME: We're already grabbing the list of statuses, we should probably not hardcode here - $this->log("No status field found, defaulting to id 1."); - $status_id = $this->status_labels->first()->id; - } - - if (!$editingAsset) { - $asset->asset_tag = $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($item['item_name'])) { - $asset->name = $item["item_name"]; - } - if (!empty($item["purchase_date"])) { - $asset->purchase_date = $item["purchase_date"]; - } - - if (array_key_exists('custom_fields', $item)) { - foreach ($item['custom_fields'] as $custom_field => $val) { - $asset->{$custom_field} = $val; - } - } - - if (!empty($item["purchase_cost"])) { - //TODO How to generalize this for not USD? - $purchase_cost = substr($item["purchase_cost"], 0, 1) === '$' ? substr($item["purchase_cost"], 1) : $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 ($item["user"]) { - $asset->assigned_to = $item["user"]->id; - } - - if (isset($item["location"])) { - $asset->rtd_location_id = $item["location"]->id; - } - - $asset->user_id = $this->option('user_id'); - if (isset($status_id)) { - $asset->status_id = $status_id; - } - if (isset($item["company"])) { - $asset->company_id = $item["company"]->id; - } - if ($item["order_number"]) { - $asset->order_number = $item["order_number"]; - } - if (isset($supplier)) { - $asset->supplier_id = $supplier->id; - } - if ($item["notes"]) { - $asset->notes = $item["notes"]; - } - if (!empty($asset_image)) { - $asset->image = $asset_image; - } - if (!$editingAsset) { - $this->assets->add($asset); - } - if (!$this->option('testrun')) { - - if ($asset->save()) { - $asset->logCreate('Imported using csv importer'); - $this->log('Asset ' . $item["item_name"] . ' with serial number ' . $asset_serial . ' was created'); - } else { - $this->jsonError('Asset', $asset->getErrors()); - } - - } else { - return; - } - } - - private $accessories; - - /** - * Create an accessory if a duplicate does not exist - * - * @author Daniel Melzter - * @since 3.0 - * @param $item array - */ - public function createAccessoryIfNotExists(array $item) - { - $accessory = null; - $editingAccessory = false; - $this->log("Creating Accessory"); - foreach ($this->accessories as $tempaccessory) { - if (strcasecmp($tempaccessory->name, $item["item_name"]) == 0) { - $this->log('A matching Accessory ' . $item["item_name"] . ' already exists. '); - if (!$this->option('update')) { - $this->log("Skipping accessory."); - return; - } - $this->log('Updating matching accessory with new values'); - $editingAccessory = true; - $accessory = $tempaccessory; - } - } - if (is_null($accessory)) { - $this->log("No Matching Accessory, Creating a new one"); - $accessory = new Accessory(); - } - - if (!$editingAccessory) { - $accessory->name = $item["item_name"]; - } - - if (!empty($item["purchase_date"])) { - $accessory->purchase_date = $item["purchase_date"]; - } else { - $accessory->purchase_date = null; - } - if (!empty($item["purchase_cost"])) { - $accessory->purchase_cost = Helper::ParseFloat($item["purchase_cost"]); - } - - if (isset($item["location"])) { - $accessory->location_id = $item["location"]->id; - } - $accessory->user_id = $this->option('user_id'); - if (isset($item["company"])) { - $accessory->company_id = $item["company"]->id; - } - if (!empty($item["order_number"])) { - $accessory->order_number = $item["order_number"]; - } - if (isset($item["category"])) { - $accessory->category_id = $item["category"]->id; - } - - //TODO: Implement -// $accessory->notes = e($item_notes); - if (!empty($item["requestable"])) { - $accessory->requestable = filter_var($item["requestable"], FILTER_VALIDATE_BOOLEAN); - } - - //Must have at least zero of the item if we import it. - if (!empty($item["quantity"])) { - if ($item["quantity"] > -1) { - $accessory->qty = $item["quantity"]; - } else { - $accessory->qty = 1; - } - } - - if (!$this->option('testrun')) { - if ($accessory->save()) { - $accessory->logCreate('Imported using CSV Importer'); - $this->log('Accessory ' . $item["item_name"] . ' was created'); - // $this->comment('Accessory ' . $item["item_name"] . ' was created'); - - } else { - $this->jsonError('Accessory', $accessory->getErrors()) ; - } - } else { - $this->log('TEST RUN - Accessory ' . $item["item_name"] . ' not created'); - } - } - - private $consumables; - - /** - * Create a consumable if a duplicate does not exist - * - * @author Daniel Melzter - * @since 3.0 - * @param $item array - */ - public function createConsumableIfNotExists(array $item) - { - $consumable = null; - $editingConsumable = false; - $this->log("Creating Consumable"); - foreach ($this->consumables as $tempconsumable) { - if (strcasecmp($tempconsumable->name, $item["item_name"]) == 0) { - $this->log("A matching consumable " . $item["item_name"] . " already exists"); - if (!$this->option('update')) { - $this->log("Skipping consumable."); - return; - } - $this->log('Updating matching consumable with new values'); - $editingConsumable = true; - $consumable = $tempconsumable; - } - } - - if (is_null($consumable)) { - $this->log("No matching consumable, creating one"); - $consumable = new Consumable(); - } - if (!$editingConsumable) { - $consumable->name = $item["item_name"]; - } - if (!empty($item["purchase_date"])) { - $consumable->purchase_date = $item["purchase_date"]; - } else { - $consumable->purchase_date = null; - } - - if (!empty($item["purchase_cost"])) { - $consumable->purchase_cost = Helper::ParseFloat($item["purchase_cost"]); - } - if (isset($item["location"])) { - $consumable->location_id = $item["location"]->id; - } - $consumable->user_id = $this->option('user_id'); - if (isset($item["company"])) { - $consumable->company_id = $item["company"]->id; - } - if (!empty($item["order_number"])) { - $consumable->order_number = $item["order_number"]; - } - if (isset($item["category"])) { - $consumable->category_id = $item["category"]->id; - } - // TODO:Implement - //$consumable->notes= e($item_notes); - if (!empty($item["requestable"])) { - $consumable->requestable = filter_var($item["requestable"], FILTER_VALIDATE_BOOLEAN); - } - - if (!empty($item["quantity"])) { - if ($item["quantity"] > -1) { - $consumable->qty = $item["quantity"]; - } else { - $consumable->qty = 1; - } - } - - if (!$this->option("testrun")) { - // dd($consumable); - if ($consumable->save()) { - $consumable->logCreate('Imported using CSV Importer'); - $this->log("Consumable " . $item["item_name"] . ' was created'); - // $this->comment("Consumable " . $item["item_name"] . ' was created'); - - } else { - $this->jsonError('Consumable', $consumable->getErrors()); - } - } else { - $this->log('TEST RUN - Consumable ' . $item['item_name'] . ' not created'); - } - } - /** * Get the console command arguments. * diff --git a/app/Http/Controllers/AssetsController.php b/app/Http/Controllers/AssetsController.php index 23fab7b5cb..0e125f8fca 100755 --- a/app/Http/Controllers/AssetsController.php +++ b/app/Http/Controllers/AssetsController.php @@ -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')); } diff --git a/app/Http/Requests/ItemImportRequest.php b/app/Http/Requests/ItemImportRequest.php new file mode 100644 index 0000000000..4e0489e42f --- /dev/null +++ b/app/Http/Requests/ItemImportRequest.php @@ -0,0 +1,83 @@ +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; +} diff --git a/app/Importer/AccessoryImporter.php b/app/Importer/AccessoryImporter.php new file mode 100644 index 0000000000..4da6e13d63 --- /dev/null +++ b/app/Importer/AccessoryImporter.php @@ -0,0 +1,110 @@ +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'); + } + } +} \ No newline at end of file diff --git a/app/Importer/AssetImporter.php b/app/Importer/AssetImporter.php new file mode 100644 index 0000000000..9cddd49f0c --- /dev/null +++ b/app/Importer/AssetImporter.php @@ -0,0 +1,176 @@ +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()); + } + } + } +} \ No newline at end of file diff --git a/app/Importer/ConsumableImporter.php b/app/Importer/ConsumableImporter.php new file mode 100644 index 0000000000..fbcfa16f0e --- /dev/null +++ b/app/Importer/ConsumableImporter.php @@ -0,0 +1,105 @@ +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'); + } + } +} \ No newline at end of file diff --git a/app/Importer/Importer.php b/app/Importer/Importer.php new file mode 100644 index 0000000000..3617fac555 --- /dev/null +++ b/app/Importer/Importer.php @@ -0,0 +1,285 @@ +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 + * @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; + } +} \ No newline at end of file diff --git a/app/Importer/ItemImporter.php b/app/Importer/ItemImporter.php new file mode 100644 index 0000000000..10d1fbce96 --- /dev/null +++ b/app/Importer/ItemImporter.php @@ -0,0 +1,399 @@ +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; + } + } + + +} \ No newline at end of file