Skip to content

Commit

Permalink
Merge branch 'develop' into livewire-importer-improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
marcusmoore committed Aug 19, 2024
2 parents 94d8a54 + cb40a82 commit fa76566
Show file tree
Hide file tree
Showing 50 changed files with 477 additions and 281 deletions.
9 changes: 9 additions & 0 deletions .all-contributorsrc
Original file line number Diff line number Diff line change
Expand Up @@ -3181,6 +3181,15 @@
"contributions": [
"code"
]
},
{
"login": "Glukose1",
"name": "Glukose1",
"avatar_url": "https://avatars.githubusercontent.com/u/167117705?v=4",
"profile": "https://github.com/Glukose1",
"contributions": [
"code"
]
}
]
}
1 change: 1 addition & 0 deletions CONTRIBUTORS.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ Thanks goes to all of these wonderful people ([emoji key](https://github.com/ken
| [<img src="https://avatars.githubusercontent.com/u/47315739?v=4" width="110px;"/><br /><sub>bilias</sub>](https://github.com/bilias)<br />[💻](https://github.com/snipe/snipe-it/commits?author=bilias "Code") | [<img src="https://avatars.githubusercontent.com/u/2565989?v=4" width="110px;"/><br /><sub>coach1988</sub>](https://github.com/coach1988)<br />[💻](https://github.com/snipe/snipe-it/commits?author=coach1988 "Code") | [<img src="https://avatars.githubusercontent.com/u/11910225?v=4" width="110px;"/><br /><sub>MrM</sub>](https://github.com/mauro-miatello)<br />[💻](https://github.com/snipe/snipe-it/commits?author=mauro-miatello "Code") | [<img src="https://avatars.githubusercontent.com/u/60405354?v=4" width="110px;"/><br /><sub>koiakoia</sub>](https://github.com/koiakoia)<br />[💻](https://github.com/snipe/snipe-it/commits?author=koiakoia "Code") | [<img src="https://avatars.githubusercontent.com/u/5323832?v=4" width="110px;"/><br /><sub>Mustafa Online</sub>](https://github.com/mustafa-online)<br />[💻](https://github.com/snipe/snipe-it/commits?author=mustafa-online "Code") | [<img src="https://avatars.githubusercontent.com/u/104601439?v=4" width="110px;"/><br /><sub>franceslui</sub>](https://github.com/franceslui)<br />[💻](https://github.com/snipe/snipe-it/commits?author=franceslui "Code") | [<img src="https://avatars.githubusercontent.com/u/125313163?v=4" width="110px;"/><br /><sub>Q4kK</sub>](https://github.com/Q4kK)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Q4kK "Code") |
| [<img src="https://avatars.githubusercontent.com/u/55590532?v=4" width="110px;"/><br /><sub>squintfox</sub>](https://github.com/squintfox)<br />[💻](https://github.com/snipe/snipe-it/commits?author=squintfox "Code") | [<img src="https://avatars.githubusercontent.com/u/1380084?v=4" width="110px;"/><br /><sub>Jeff Clay</sub>](https://github.com/jeffclay)<br />[💻](https://github.com/snipe/snipe-it/commits?author=jeffclay "Code") | [<img src="https://avatars.githubusercontent.com/u/52716446?v=4" width="110px;"/><br /><sub>Phil J R</sub>](https://github.com/PP-JN-RL)<br />[💻](https://github.com/snipe/snipe-it/commits?author=PP-JN-RL "Code") | [<img src="https://avatars.githubusercontent.com/u/1496725?v=4" width="110px;"/><br /><sub>i_virus</sub>](https://www.corelight.com/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=chandanchowdhury "Code") | [<img src="https://avatars.githubusercontent.com/u/1020541?v=4" width="110px;"/><br /><sub>Paul Grime</sub>](https://github.com/gitgrimbo)<br />[💻](https://github.com/snipe/snipe-it/commits?author=gitgrimbo "Code") | [<img src="https://avatars.githubusercontent.com/u/922815?v=4" width="110px;"/><br /><sub>Lee Porte</sub>](https://leeporte.co.uk)<br />[💻](https://github.com/snipe/snipe-it/commits?author=LeePorte "Code") | [<img src="https://avatars.githubusercontent.com/u/23613427?v=4" width="110px;"/><br /><sub>BRYAN </sub>](https://github.com/bryanlopezinc)<br />[💻](https://github.com/snipe/snipe-it/commits?author=bryanlopezinc "Code") [⚠️](https://github.com/snipe/snipe-it/commits?author=bryanlopezinc "Tests") |
| [<img src="https://avatars.githubusercontent.com/u/64061710?v=4" width="110px;"/><br /><sub>U-H-T</sub>](https://github.com/U-H-T)<br />[💻](https://github.com/snipe/snipe-it/commits?author=U-H-T "Code") | [<img src="https://avatars.githubusercontent.com/u/5395363?v=4" width="110px;"/><br /><sub>Matt Tyree</sub>](https://github.com/Tyree)<br />[📖](https://github.com/snipe/snipe-it/commits?author=Tyree "Documentation") | [<img src="https://avatars.githubusercontent.com/u/292081?v=4" width="110px;"/><br /><sub>Florent Bervas</sub>](http://spoontux.net)<br />[💻](https://github.com/snipe/snipe-it/commits?author=FlorentDotMe "Code") | [<img src="https://avatars.githubusercontent.com/u/4498077?v=4" width="110px;"/><br /><sub>Daniel Albertsen</sub>](https://ditscheri.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=dbakan "Code") | [<img src="https://avatars.githubusercontent.com/u/100710244?v=4" width="110px;"/><br /><sub>r-xyz</sub>](https://github.com/r-xyz)<br />[💻](https://github.com/snipe/snipe-it/commits?author=r-xyz "Code") | [<img src="https://avatars.githubusercontent.com/u/47491036?v=4" width="110px;"/><br /><sub>Steven Mainor</sub>](https://github.com/DrekiDegga)<br />[💻](https://github.com/snipe/snipe-it/commits?author=DrekiDegga "Code") | [<img src="https://avatars.githubusercontent.com/u/65785975?v=4" width="110px;"/><br /><sub>arne-kroeger</sub>](https://github.com/arne-kroeger)<br />[💻](https://github.com/snipe/snipe-it/commits?author=arne-kroeger "Code") |
| [<img src="https://avatars.githubusercontent.com/u/167117705?v=4" width="110px;"/><br /><sub>Glukose1</sub>](https://github.com/Glukose1)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Glukose1 "Code") |
<!-- ALL-CONTRIBUTORS-LIST:END -->

This project follows the [all-contributors](https://github.com/kentcdodds/all-contributors) specification. Contributions of any kind welcome!
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,13 @@ Since the release of the JSON REST API, several third-party developers have been
- [Snipe-IT plugin for Jira Service Desk](https://marketplace.atlassian.com/apps/1220964/snipe-it-for-jira)
- [Python 3 CSV importer](https://github.com/gastamper/snipeit-csvimporter) - allows importing assets into Snipe-IT based on Item Name rather than Asset Tag.
- [Snipe-IT Kubernetes Helm Chart](https://github.com/t3n/helm-charts/tree/master/snipeit) - For more information, [click here](https://hub.helm.sh/charts/t3n/snipeit).
- [Snipe-IT Bulk Edit](https://github.com/bricelabelle/snipe-it-bulkedit) - Google Script files to use Google Sheets as a bulk checkout/checkin/edit tool for Snipe-it.
- [MosyleSnipeSync](https://github.com/RodneyLeeBrands/MosyleSnipeSync) by [@Karpadiem](https://github.com/Karpadiem) - Python script to synchronize information between Mosyle and Snipe-IT
- [Snipe-IT Bulk Edit](https://github.com/bricelabelle/snipe-it-bulkedit) - Google Script files to use Google Sheets as a bulk checkout/checkin/edit tool for Snipe-IT.
- [MosyleSnipeSync](https://github.com/RodneyLeeBrands/MosyleSnipeSync) by [@Karpadiem](https://github.com/Karpadiem) - Python script to synchronize information between Mosyle and Snipe-IT.
- [WWW::SnipeIT](https://github.com/SEDC/perl-www-snipeit) by [@SEDC](https://github.com/SEDC) - perl module for accessing the API
- [UniFi to Snipe-IT](https://github.com/RodneyLeeBrands/UnifiSnipeSync) by [@karpadiem](https://github.com/karpadiem) - Python script that synchronizes UniFi devices with Snipe-IT.
- [Kandji2Snipe](https://github.com/grokability/kandji2snipe) by [@briangoldstein](https://github.com/briangoldstein) - Python script that synchronizes Kandji with Snipe-IT.
- [SnipeAgent](https://github.com/ReticentRobot/SnipeAgent) by @ReticentRobot - Windows agent for Snipe-IT
- [SnipeAgent](https://github.com/ReticentRobot/SnipeAgent) by [@ReticentRobot](https://github.com/ReticentRobot) - Windows agent for Snipe-IT.
- [Gate Pass Generator](https://github.com/cha7uraAE/snipe-it-gate-pass-system) by [@cha7uraAE](https://github.com/cha7uraAE) - A Streamlit application for generating gate passes based on hardware data from a Snipe-IT API.

-----

Expand Down
2 changes: 1 addition & 1 deletion app/Http/Controllers/Api/PredefinedKitsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ public function storeModel(Request $request, $kit_id) : JsonResponse

$relation = $kit->models();
if ($relation->find($model_id)) {
return response()->json(Helper::formatStandardApiResponse('error', null, ['model' => 'Model already attached to kit']));
return response()->json(Helper::formatStandardApiResponse('error', null, ['model' => trans('admin/kits/general.model_already_attached')]));
}
$relation->attach($model_id, ['quantity' => $quantity]);

Expand Down
4 changes: 2 additions & 2 deletions app/Http/Controllers/Auth/LoginController.php
Original file line number Diff line number Diff line change
Expand Up @@ -508,8 +508,8 @@ public function logout(Request $request)
protected function validator(array $data)
{
return Validator::make($data, [
'username' => 'required',
'password' => 'required',
'username' => 'required|not_array',
'password' => 'required|not_array',
]);
}

Expand Down
4 changes: 2 additions & 2 deletions app/Http/Controllers/Kits/CheckoutKitController.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,10 @@ public function store(Request $request, $kit_id)

$checkout_result = $this->kitService->checkout($request, $kit, $user);
if (Arr::has($checkout_result, 'errors') && count($checkout_result['errors']) > 0) {
return redirect()->back()->with('error', trans('general.checkout_error'))->with('error_messages', $checkout_result['errors']);
return redirect()->back()->with('error', trans('admin/kits/general.checkout_error'))->with('error_messages', $checkout_result['errors']);
}

return redirect()->back()->with('success', trans('general.checkout_success'))
return redirect()->back()->with('success', trans('admin/kits/general.checkout_success'))
->with('assets', Arr::get($checkout_result, 'assets', null))
->with('accessories', Arr::get($checkout_result, 'accessories', null))
->with('consumables', Arr::get($checkout_result, 'consumables', null));
Expand Down
1 change: 1 addition & 0 deletions app/Http/Controllers/SettingsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -637,6 +637,7 @@ public function postAlerts(Request $request) : RedirectResponse
$setting->alert_threshold = $request->input('alert_threshold');
$setting->audit_interval = $request->input('audit_interval');
$setting->audit_warning_days = $request->input('audit_warning_days');
$setting->due_checkin_days = $request->input('due_checkin_days');
$setting->show_alerts_in_menu = $request->input('show_alerts_in_menu', '0');

if ($setting->save()) {
Expand Down
1 change: 1 addition & 0 deletions app/Http/Kernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ class Kernel extends HttpKernel

'api' => [
'auth:api',
\App\Http\Middleware\CheckLocale::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
];
Expand Down
4 changes: 3 additions & 1 deletion app/Http/Traits/TwoColumnUniqueUndeletedTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,17 @@ trait TwoColumnUniqueUndeletedTrait
* @param string $field
* @return string
*/
protected function prepareTwoColumnUniqueUndeletedRule($parameters, $field)
protected function prepareTwoColumnUniqueUndeletedRule($parameters)
{
$column = $parameters[0];
$value = $this->{$parameters[0]};

// This is an existing model we're updating so ignore the current ID ($this->getKey())
if ($this->exists) {
return 'two_column_unique_undeleted:'.$this->table.','.$this->getKey().','.$column.','.$value;
}

// This is a new record, so we can ignore the current ID
return 'two_column_unique_undeleted:'.$this->table.',0,'.$column.','.$value;
}
}
2 changes: 1 addition & 1 deletion app/Http/Transformers/AssetsTransformer.php
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public function transformAsset(Asset $asset)
'next_audit_date' => Helper::getFormattedDateObject($asset->next_audit_date, 'date'),
'deleted_at' => Helper::getFormattedDateObject($asset->deleted_at, 'datetime'),
'purchase_date' => Helper::getFormattedDateObject($asset->purchase_date, 'date'),
'age' => $asset->purchase_date ? $asset->purchase_date->diffForHumans() : '',
'age' => $asset->purchase_date ? $asset->purchase_date->locale(app()->getLocale())->diffForHumans() : '',
'last_checkout' => Helper::getFormattedDateObject($asset->last_checkout, 'datetime'),
'last_checkin' => Helper::getFormattedDateObject($asset->last_checkin, 'datetime'),
'expected_checkin' => Helper::getFormattedDateObject($asset->expected_checkin, 'date'),
Expand Down
6 changes: 4 additions & 2 deletions app/Importer/AssetImporter.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,10 @@ public function createAssetIfNotExists(array $row)
$asset = Asset::where(['asset_tag'=> (string) $asset_tag])->first();
if ($asset) {
if (! $this->updating) {
$this->log('A matching Asset '.$asset_tag.' already exists');
return;
$exists_error = trans('general.import_asset_tag_exists', ['asset_tag' => $asset_tag]);
$this->log($exists_error);
$this->addErrorToBag($asset, 'asset_tag', $exists_error);
return $exists_error;
}

$this->log('Updating Asset');
Expand Down
7 changes: 7 additions & 0 deletions app/Importer/Importer.php
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,13 @@ protected function logError($item, $field)
}
}

protected function addErrorToBag($item, $field, $error_message)
{
if ($this->errorCallback) {
call_user_func($this->errorCallback, $item, $field, [$field => [$error_message]]);
}
}

/**
* Finds the user matching given data, or creates a new one if there is no match.
* This is NOT used by the User Import, only for Asset/Accessory/etc where
Expand Down
33 changes: 23 additions & 10 deletions app/Importer/ItemImporter.php
Original file line number Diff line number Diff line change
Expand Up @@ -196,64 +196,77 @@ public function createOrFetchAssetModel(array $row)
{
$condition = array();
$asset_model_name = $this->findCsvMatch($row, 'asset_model');
$asset_model_category = $this->findCsvMatch($row, 'category');
$asset_modelNumber = $this->findCsvMatch($row, 'model_number');

// TODO: At the moment, this means we can't update the model number if the model name stays the same.
if (! $this->shouldUpdateField($asset_model_name)) {
return;
}

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';
}

if ((!empty($asset_model_name)) && (empty($asset_modelNumber))) {
$condition[] = ['name', '=', $asset_model_name];
} elseif ((!empty($asset_model_name)) && (!empty($asset_modelNumber))) {
$condition[] = ['name', '=', $asset_model_name];
$condition[] = ['model_number', '=', $asset_modelNumber];
$asset_model = AssetModel::select('id');

if (!empty($asset_model_name)) {
$asset_model = $asset_model->where('name', '=', $asset_model_name);

if (!empty($asset_modelNumber)) {
$asset_model = $asset_model->where('model_number', '=', $asset_modelNumber);
}
}

$editingModel = $this->updating;
$asset_model = AssetModel::where($condition)->first();
$asset_model = $asset_model->first();

if ($asset_model) {

if (! $this->updating) {
$this->log('A matching model already exists, returning it.');

return $asset_model->id;
}

$this->log('Matching Model found, updating it.');
$item = $this->sanitizeItemForStoring($asset_model, $editingModel);
$item['name'] = $asset_model_name;
$item['notes'] = $this->findCsvMatch($row, 'model_notes');

if(!empty($asset_modelNumber)){
if (!empty($asset_modelNumber)){
$item['model_number'] = $asset_modelNumber;
}

$asset_model->update($item);
$asset_model->save();
$this->log('Asset Model Updated');

return $asset_model->id;

}
$this->log('No Matching Model, Creating a new one');

$this->log('No Matching Model, Creating a new one');
$asset_model = new AssetModel();
$item = $this->sanitizeItemForStoring($asset_model, $editingModel);
$item['name'] = $asset_model_name;
$item['model_number'] = $asset_modelNumber;
$item['notes'] = $this->findCsvMatch($row, 'model_notes');
$item['category_id'] = $this->createOrFetchCategory($asset_model_category);

$asset_model->fill($item);
//$asset_model = AssetModel::firstOrNew($item);
$item = null;



if ($asset_model->save()) {
$this->log('Asset Model '.$asset_model_name.' with model number '.$asset_modelNumber.' was created');

return $asset_model->id;
}
$this->log('Asset Model Errors: '.$asset_model->getErrors());
$this->logError($asset_model, 'Asset Model "'.$asset_model_name.'"');

return null;
Expand Down
6 changes: 6 additions & 0 deletions app/Livewire/Importer.php
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,12 @@ public function mount()
'model name',
'model',
],
'eol_date' =>
[
'eol',
'eol date',
'asset eol date',
],
'gravatar' =>
[
'gravatar',
Expand Down
2 changes: 1 addition & 1 deletion app/Models/Asset.php
Original file line number Diff line number Diff line change
Expand Up @@ -1315,7 +1315,7 @@ public function scopeDueOrOverdueForAudit($query, $settings)

public function scopeDueForCheckin($query, $settings)
{
$interval = $settings->audit_warning_days ?? 0;
$interval = $settings->due_checkin_days ?? 0;
$today = Carbon::now();
$interval_date = $today->copy()->addDays($interval)->format('Y-m-d');

Expand Down
33 changes: 21 additions & 12 deletions app/Models/AssetModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use Illuminate\Support\Facades\Storage;
use Watson\Validating\ValidatingTrait;
use \App\Presenters\AssetModelPresenter;
use App\Http\Traits\TwoColumnUniqueUndeletedTrait;

/**
* Model for Asset Models. Asset Models contain higher level
Expand All @@ -21,31 +22,36 @@ class AssetModel extends SnipeModel
{
use HasFactory;
use SoftDeletes;
protected $presenter = AssetModelPresenter::class;
use Loggable, Requestable, Presentable;
use TwoColumnUniqueUndeletedTrait;

/**
* Whether the model should inject its identifier to the unique
* validation rules before attempting validation. If this property
* is not set in the model it will default to true.
*
* @var bool
*/

protected $injectUniqueIdentifier = true;
use ValidatingTrait;
protected $table = 'models';
protected $hidden = ['user_id', 'deleted_at'];
protected $presenter = AssetModelPresenter::class;

// Declare the rules for the model validation


protected $rules = [
'name' => 'string|required|min:1|max:255|unique:models,name',
'model_number' => 'string|max:255|nullable',
'name' => 'string|required|min:1|max:255|two_column_unique_undeleted:model_number',
'model_number' => 'string|max:255|nullable|two_column_unique_undeleted:name',
'min_amt' => 'integer|min:0|nullable',
'category_id' => 'required|integer|exists:categories,id',
'manufacturer_id' => 'integer|exists:manufacturers,id|nullable',
'eol' => 'integer:min:0|max:240|nullable',
];

/**
* Whether the model should inject its identifier to the unique
* validation rules before attempting validation. If this property
* is not set in the model it will default to true.
*
* @var bool
*/
protected $injectUniqueIdentifier = true;
use ValidatingTrait;


/**
* The attributes that are mass assignable.
Expand Down Expand Up @@ -86,6 +92,9 @@ class AssetModel extends SnipeModel
'manufacturer' => ['name'],
];




/**
* Establishes the model -> assets relationship
*
Expand Down
3 changes: 3 additions & 0 deletions app/Models/Setting.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,10 @@ class Setting extends Model
'login_remote_user_header_name' => 'string|nullable',
'thumbnail_max_h' => 'numeric|max:500|min:25',
'pwd_secure_min' => 'numeric|required|min:8',
'alert_threshold' => 'numeric|nullable',
'alert_interval' => 'numeric|nullable',
'audit_warning_days' => 'numeric|nullable',
'due_checkin_days' => 'numeric|nullable',
'audit_interval' => 'numeric|nullable',
'custom_forgot_pass_url' => 'url|nullable',
'privacy_policy_link' => 'nullable|url',
Expand Down
Loading

0 comments on commit fa76566

Please sign in to comment.