Skip to content

Commit 934b392

Browse files
committed
Merge remote-tracking branch 'origin/develop'
2 parents efe95d9 + 67315d8 commit 934b392

File tree

385 files changed

+3169
-2109
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

385 files changed

+3169
-2109
lines changed

.env.example

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ MAIL_USERNAME=YOURUSERNAME
3030
MAIL_PASSWORD=YOURPASSWORD
3131
MAIL_ENCRYPTION=null
3232
MAIL_FROM_ADDR=[email protected]
33-
MAIL_FROM_NAME=Snipe-IT
33+
MAIL_FROM_NAME='Snipe-IT'
3434

3535

3636
# --------------------------------------------
@@ -74,4 +74,5 @@ AWS_BUCKET=null
7474
APP_LOG=single
7575
APP_LOCKED=false
7676
FILESYSTEM_DISK=local
77-
APP_TRUSTED_PROXIES=192.168.1.1,10.0.0.1
77+
APP_TRUSTED_PROXIES=192.168.1.1,10.0.0.1
78+
ALLOW_IFRAMING=false

app/Console/Commands/ObjectImportCommand.php

Lines changed: 146 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,27 @@
11
<?php
22
namespace App\Console\Commands;
33

4-
use Illuminate\Console\Command;
5-
use Symfony\Component\Console\Input\InputOption;
6-
use Symfony\Component\Console\Input\InputArgument;
7-
use League\Csv\Reader;
4+
use App\Helpers\Helper;
85
use App\Models\Accessory;
96
use App\Models\Asset;
107
use App\Models\AssetModel;
118
use App\Models\Category;
129
use App\Models\Company;
1310
use App\Models\Consumable;
11+
use App\Models\CustomField;
1412
use App\Models\Location;
1513
use App\Models\Manufacturer;
14+
use App\Models\Setting;
1615
use App\Models\Statuslabel;
1716
use App\Models\Supplier;
1817
use App\Models\User;
19-
use App\Models\CustomField;
2018
use DB;
21-
use App\Models\Setting;
19+
use Illuminate\Console\Command;
2220
use Illuminate\Database\Eloquent\Model;
21+
use League\Csv\Reader;
22+
use Symfony\Component\Console\Input\InputArgument;
23+
use Symfony\Component\Console\Input\InputOption;
24+
use ForceUTF8\Encoding;
2325

2426
ini_set('max_execution_time', 600); //600 seconds = 10 minutes
2527
ini_set('memory_limit', '500M');
@@ -102,9 +104,17 @@ public function fire()
102104
$this->companies = Company::All(['name', 'id']);
103105
$this->status_labels = Statuslabel::All(['name', 'id']);
104106
$this->suppliers = Supplier::All(['name', 'id']);
105-
$this->assets = Asset::all(['asset_tag']);
106-
$this->accessories = Accessory::All(['name']);
107-
$this->consumables = Consumable::All(['name']);
107+
switch (strtolower($this->option('item-type'))) {
108+
case "asset":
109+
$this->assets = Asset::all();
110+
break;
111+
case "accessory":
112+
$this->accessories = Accessory::All();
113+
break;
114+
case "consumable":
115+
$this->consumables = Consumable::All();
116+
break;
117+
}
108118
$this->customfields = CustomField::All(['name']);
109119
$bar = null;
110120

@@ -275,7 +285,7 @@ private function log($string, $level = 'info')
275285
*/
276286
public function array_smart_fetch(array $array, $key, $default = '')
277287
{
278-
return array_key_exists($key, $array) ? e(trim($array[ $key ])) : $default;
288+
return array_key_exists(trim($key), $array) ? e(Encoding::fixUTF8(trim($array[ $key ]))) : $default;
279289
}
280290

281291

@@ -313,7 +323,7 @@ public function createOrFetchAssetModel(array $row, $category, $manufacturer)
313323
$asset_model_name = $this->array_smart_fetch($row, "model name");
314324
$asset_modelno = $this->array_smart_fetch($row, "model number");
315325
if (empty($asset_model_name)) {
316-
$asset_model_name='Unknown';
326+
$asset_model_name ='Unknown';
317327
}
318328
if (empty($asset_modelno)) {
319329
$asset_modelno='';
@@ -346,6 +356,7 @@ public function createOrFetchAssetModel(array $row, $category, $manufacturer)
346356
return $asset_model;
347357
} else {
348358
$this->jsonError('Asset Model "' . $asset_model_name . '"', $asset_model->getErrors());
359+
$this->log('Asset Model "' . $asset_model_name . '"', $asset_model->getErrors());
349360
return $asset_model;
350361
}
351362
} else {
@@ -732,6 +743,24 @@ public function createOrFetchUser($row, $password = null)
732743
*/
733744
public function createAssetIfNotExists(array $row, array $item)
734745
{
746+
$asset = null;
747+
$editingAsset = false;
748+
foreach ($this->assets as $tempasset) {
749+
if (strcasecmp($tempasset->asset_tag, $item['asset_tag']) == 0) {
750+
$this->log('A matching Asset ' . $item['asset_tag'] . ' already exists');
751+
if (!$this->option('update')) {
752+
$this->log("Skipping item.");
753+
return;
754+
}
755+
$this->log('Updating matching asset with new values');
756+
$editingAsset = true;
757+
$asset = $tempasset;
758+
}
759+
}
760+
if (is_null($asset)) {
761+
$this->log("No Matching Asset, Creating a new one");
762+
$asset = new Asset;
763+
}
735764
$asset_serial = $this->array_smart_fetch($row, "serial number");
736765
$asset_image = $this->array_smart_fetch($row, "image");
737766
$asset_warranty_months = intval($this->array_smart_fetch($row, "warranty months"));
@@ -747,12 +776,7 @@ public function createAssetIfNotExists(array $row, array $item)
747776
$this->log('Notes: '.$item["notes"]);
748777
$this->log('Warranty Months: ' . $asset_warranty_months);
749778

750-
foreach ($this->assets as $tempasset) {
751-
if (strcasecmp($tempasset->asset_tag, $item['asset_tag']) == 0) {
752-
$this->log('A matching Asset ' . $item['asset_tag'] . ' already exists');
753-
return;
754-
}
755-
}
779+
756780

757781
if ($item["status_label"]) {
758782
$status_id = $item["status_label"]->id;
@@ -763,12 +787,14 @@ public function createAssetIfNotExists(array $row, array $item)
763787
$status_id = 1;
764788
}
765789

766-
$asset = new Asset();
767-
$asset->name = $item["item_name"];
768-
if ($item["purchase_date"] != '') {
790+
if (!$editingAsset) {
791+
$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.
792+
}
793+
if (!empty($item['item_name'])) {
794+
$asset->name = $item["item_name"];
795+
}
796+
if (!empty($item["purchase_date"])) {
769797
$asset->purchase_date = $item["purchase_date"];
770-
} else {
771-
$asset->purchase_date = null;
772798
}
773799

774800
if (array_key_exists('custom_fields', $item)) {
@@ -780,37 +806,53 @@ public function createAssetIfNotExists(array $row, array $item)
780806
if (!empty($item["purchase_cost"])) {
781807
//TODO How to generalize this for not USD?
782808
$purchase_cost = substr($item["purchase_cost"], 0, 1) === '$' ? substr($item["purchase_cost"], 1) : $item["purchase_cost"];
783-
$asset->purchase_cost = number_format($purchase_cost, 2, '.', '');
809+
// $asset->purchase_cost = number_format($purchase_cost, 2, '.', '');
810+
$asset->purchase_cost = Helper::ParseFloat($purchase_cost);
784811
$this->log("Asset cost parsed: " . $asset->purchase_cost);
785812
} else {
786813
$asset->purchase_cost = 0.00;
787814
}
788-
$asset->serial = $asset_serial;
789-
$asset->asset_tag = $item['asset_tag'];
790-
$asset->warranty_months = $asset_warranty_months;
815+
if (!empty($asset_serial)) {
816+
$asset->serial = $asset_serial;
817+
}
818+
if (!empty($asset_warranty_months)) {
819+
$asset->warranty_months = $asset_warranty_months;
820+
}
791821

792822
if ($asset_model) {
793823
$asset->model_id = $asset_model->id;
794824
}
825+
795826
if ($item["user"]) {
796827
$asset->assigned_to = $item["user"]->id;
797828
}
829+
798830
if ($item["location"]) {
799831
$asset->rtd_location_id = $item["location"]->id;
800832
}
833+
801834
$asset->user_id = $this->option('user_id');
802-
$this->log("status_id: " . $status_id);
803-
$asset->status_id = $status_id;
835+
if (!empty($status_id)) {
836+
$asset->status_id = $status_id;
837+
}
804838
if ($item["company"]) {
805839
$asset->company_id = $item["company"]->id;
806840
}
807-
$asset->order_number = $item["order_number"];
841+
if ($item["order_number"]) {
842+
$asset->order_number = $item["order_number"];
843+
}
808844
if ($supplier) {
809845
$asset->supplier_id = $supplier->id;
810846
}
811-
$asset->notes = $item["notes"];
812-
$asset->image = $asset_image;
813-
$this->assets->add($asset);
847+
if ($item["notes"]) {
848+
$asset->notes = $item["notes"];
849+
}
850+
if (!empty($asset_image)) {
851+
$asset->image = $asset_image;
852+
}
853+
if (!$editingAsset) {
854+
$this->assets->add($asset);
855+
}
814856
if (!$this->option('testrun')) {
815857

816858
if ($asset->save()) {
@@ -835,49 +877,66 @@ public function createAssetIfNotExists(array $row, array $item)
835877
*/
836878
public function createAccessoryIfNotExists(array $item)
837879
{
880+
$accessory = null;
881+
$editingAccessory = false;
838882
$this->log("Creating Accessory");
839883
foreach ($this->accessories as $tempaccessory) {
840884
if (strcasecmp($tempaccessory->name, $item["item_name"]) == 0) {
841885
$this->log('A matching Accessory ' . $item["item_name"] . ' already exists. ');
842-
// FUTURE: Adjust quantity on import maybe?
843-
return;
886+
if (!$this->option('update')) {
887+
$this->log("Skipping accessory.");
888+
return;
889+
}
890+
$this->log('Updating matching accessory with new values');
891+
$editingAccessory = true;
892+
$accessory = $tempaccessory;
844893
}
845894
}
895+
if (is_null($accessory)) {
896+
$this->log("No Matching Accessory, Creating a new one");
897+
$accessory = new Accessory();
898+
}
846899

847-
$accessory = new Accessory();
848-
$accessory->name = $item["item_name"];
900+
if (!$editingAccessory) {
901+
$accessory->name = $item["item_name"];
902+
}
849903

850904
if (!empty($item["purchase_date"])) {
851905
$accessory->purchase_date = $item["purchase_date"];
852906
} else {
853907
$accessory->purchase_date = null;
854908
}
855909
if (!empty($item["purchase_cost"])) {
856-
$accessory->purchase_cost = number_format(e($item["purchase_cost"]), 2);
857-
} else {
858-
$accessory->purchase_cost = 0.00;
910+
$accessory->purchase_cost = Helper::ParseFloat($item["purchase_cost"]);
859911
}
912+
860913
if ($item["location"]) {
861914
$accessory->location_id = $item["location"]->id;
862915
}
863916
$accessory->user_id = $this->option('user_id');
864917
if ($item["company"]) {
865918
$accessory->company_id = $item["company"]->id;
866919
}
867-
$accessory->order_number = $item["order_number"];
920+
if (!empty($item["order_number"])) {
921+
$accessory->order_number = $item["order_number"];
922+
}
868923
if ($item["category"]) {
869924
$accessory->category_id = $item["category"]->id;
870925
}
871926

872927
//TODO: Implement
873928
// $accessory->notes = e($item_notes);
874-
$accessory->requestable = filter_var($item["requestable"], FILTER_VALIDATE_BOOLEAN);
929+
if (!empty($item["requestable"])) {
930+
$accessory->requestable = filter_var($item["requestable"], FILTER_VALIDATE_BOOLEAN);
931+
}
875932

876933
//Must have at least zero of the item if we import it.
877-
if ($item["quantity"] > -1) {
878-
$accessory->qty = $item["quantity"];
879-
} else {
880-
$accessory->qty = 1;
934+
if (!empty($item["quantity"])) {
935+
if ($item["quantity"] > -1) {
936+
$accessory->qty = $item["quantity"];
937+
} else {
938+
$accessory->qty = 1;
939+
}
881940
}
882941

883942
if (!$this->option('testrun')) {
@@ -904,45 +963,67 @@ public function createAccessoryIfNotExists(array $item)
904963
*/
905964
public function createConsumableIfNotExists(array $item)
906965
{
966+
$consumable = null;
967+
$editingConsumable = false;
907968
$this->log("Creating Consumable");
908969
foreach ($this->consumables as $tempconsumable) {
909970
if (strcasecmp($tempconsumable->name, $item["item_name"]) == 0) {
910971
$this->log("A matching consumable " . $item["item_name"] . " already exists");
911-
//TODO: Adjust quantity if different maybe?
912-
return;
972+
if (!$this->option('update')) {
973+
$this->log("Skipping consumable.");
974+
return;
975+
}
976+
$this->log('Updating matching consumable with new values');
977+
$editingConsumable = true;
978+
$consumable = $tempconsumable;
913979
}
914980
}
915981

916-
$consumable = new Consumable();
917-
$consumable->name = $item["item_name"];
918-
982+
if (is_null($consumable)) {
983+
$this->log("No matching consumable, creating one");
984+
$consumable = new Consumable();
985+
}
986+
if (!$editingConsumable) {
987+
$consumable->name = $item["item_name"];
988+
}
919989
if (!empty($item["purchase_date"])) {
920990
$consumable->purchase_date = $item["purchase_date"];
921991
} else {
922992
$consumable->purchase_date = null;
923993
}
924994

925995
if (!empty($item["purchase_cost"])) {
926-
$consumable->purchase_cost = number_format(e($item["purchase_cost"]), 2);
927-
} else {
928-
$consumable->purchase_cost = 0.00;
996+
$consumable->purchase_cost = Helper::ParseFloat($item["purchase_cost"]);
997+
}
998+
if ($item["location"]) {
999+
$consumable->location_id = $item["location"]->id;
9291000
}
930-
$consumable->location_id = $item["location"]->id;
9311001
$consumable->user_id = $this->option('user_id');
932-
$consumable->company_id = $item["company"]->id;
933-
$consumable->order_number = $item["order_number"];
934-
$consumable->category_id = $item["category"]->id;
1002+
if ($item["company"]) {
1003+
$consumable->company_id = $item["company"]->id;
1004+
}
1005+
if (!empty($item["order_number"])) {
1006+
$consumable->order_number = $item["order_number"];
1007+
}
1008+
if ($item["category"]) {
1009+
$consumable->category_id = $item["category"]->id;
1010+
}
9351011
// TODO:Implement
9361012
//$consumable->notes= e($item_notes);
937-
$consumable->requestable = filter_var($item["requestable"], FILTER_VALIDATE_BOOLEAN);
1013+
if (!empty($item["requestable"])) {
1014+
$consumable->requestable = filter_var($item["requestable"], FILTER_VALIDATE_BOOLEAN);
1015+
}
9381016

939-
if ($item["quantity"] > -1) {
940-
$consumable->qty = $item["quantity"];
941-
} else {
942-
$consumable->qty = 1;
1017+
if (!empty($item["quantity"])) {
1018+
if ($item["quantity"] > -1) {
1019+
$consumable->qty = $item["quantity"];
1020+
} else {
1021+
$consumable->qty = 1;
1022+
}
9431023
}
9441024

9451025
if (!$this->option("testrun")) {
1026+
// dd($consumable);
9461027
if ($consumable->save()) {
9471028
$this->log("Consumable " . $item["item_name"] . ' was created');
9481029
// $this->comment("Consumable " . $item["item_name"] . ' was created');
@@ -985,8 +1066,9 @@ protected function getOptions()
9851066
array('testrun', null, InputOption::VALUE_NONE, 'If set, will parse and output data without adding to database', null),
9861067
array('logfile', null, InputOption::VALUE_REQUIRED, 'The path to log output to. storage/logs/importer.log by default', storage_path('logs/importer.log') ),
9871068
array('item-type', null, InputOption::VALUE_REQUIRED, 'Item Type To import. Valid Options are Asset, Consumable, Or Accessory', 'Asset'),
988-
array('web-importer', null, InputOption::VALUE_NONE, 'Internal: packages output for use with the web importer'),
989-
array('user_id', null, InputOption::VALUE_REQUIRED, 'ID of user creating items', 1)
1069+
array('web-importer', null, InputOption::VALUE_NONE, 'Internal: packages output for use with the web importer'),
1070+
array('user_id', null, InputOption::VALUE_REQUIRED, 'ID of user creating items', 1),
1071+
array('update', null, InputOption::VALUE_NONE, 'If a matching item is found, update item information'),
9901072
);
9911073

9921074
}

0 commit comments

Comments
 (0)