Merge branch 'develop' into snipeit_v7 - 2023-06-12

This commit is contained in:
Brady Wetherington 2023-06-12 16:56:23 +01:00
commit f5ff9b2208
37 changed files with 239 additions and 62 deletions

View file

@ -2916,6 +2916,42 @@
"contributions": [
"code"
]
},
{
"login": "ak-piracha",
"name": "Abdul Kareem",
"avatar_url": "https://avatars.githubusercontent.com/u/88882041?v=4",
"profile": "https://github.com/ak-piracha",
"contributions": [
"code"
]
},
{
"login": "NojoudAlshehri",
"name": "NojoudAlshehri",
"avatar_url": "https://avatars.githubusercontent.com/u/111287779?v=4",
"profile": "https://github.com/NojoudAlshehri",
"contributions": [
"code"
]
},
{
"login": "stefanstidlffg",
"name": "Stefan Stidl",
"avatar_url": "https://avatars.githubusercontent.com/u/54367449?v=4",
"profile": "https://github.com/stefanstidlffg",
"contributions": [
"code"
]
},
{
"login": "qay21",
"name": "Quentin Aymard",
"avatar_url": "https://avatars.githubusercontent.com/u/87803479?v=4",
"profile": "https://github.com/qay21",
"contributions": [
"code"
]
}
]
}

View file

@ -38,6 +38,7 @@ gcc \
make \
autoconf \
libc-dev \
libldap-common \
pkg-config \
libmcrypt-dev \
php8.1-dev \

View file

@ -1,5 +1,5 @@
![Build Status](https://app.chipperci.com/projects/0e5f8979-31eb-4ee6-9abf-050b76ab0383/status/master) [![Crowdin](https://d322cqt584bo4o.cloudfront.net/snipe-it/localized.svg)](https://crowdin.com/project/snipe-it) [![Docker Pulls](https://img.shields.io/docker/pulls/snipe/snipe-it.svg)](https://hub.docker.com/r/snipe/snipe-it/) [![Twitter Follow](https://img.shields.io/twitter/follow/snipeitapp.svg?style=social)](https://twitter.com/snipeitapp) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/553ce52037fc43ea99149785afcfe641)](https://www.codacy.com/app/snipe/snipe-it?utm_source=github.com&utm_medium=referral&utm_content=snipe/snipe-it&utm_campaign=Badge_Grade)
[![All Contributors](https://img.shields.io/badge/all_contributors-321-orange.svg?style=flat-square)](#contributors) [![Discord](https://badgen.net/badge/icon/discord?icon=discord&label)](https://discord.gg/yZFtShAcKk) [![huntr](https://cdn.huntr.dev/huntr_security_badge_mono.svg)](https://huntr.dev)
[![All Contributors](https://img.shields.io/badge/all_contributors-325-orange.svg?style=flat-square)](#contributors) [![Discord](https://badgen.net/badge/icon/discord?icon=discord&label)](https://discord.gg/yZFtShAcKk) [![huntr](https://cdn.huntr.dev/huntr_security_badge_mono.svg)](https://huntr.dev)
## Snipe-IT - Open Source Asset Management System
@ -144,7 +144,8 @@ Thanks goes to all of these wonderful people ([emoji key](https://github.com/ken
| [<img src="https://avatars.githubusercontent.com/u/32363424?v=4" width="110px;"/><br /><sub>Peace</sub>](https://github.com/julian-piehl)<br />[💻](https://github.com/snipe/snipe-it/commits?author=julian-piehl "Code") | [<img src="https://avatars.githubusercontent.com/u/231528?v=4" width="110px;"/><br /><sub>Kyle Gordon</sub>](https://github.com/kylegordon)<br />[💻](https://github.com/snipe/snipe-it/commits?author=kylegordon "Code") | [<img src="https://avatars.githubusercontent.com/u/53009155?v=4" width="110px;"/><br /><sub>Katharina Drexel</sub>](http://www.bfh.ch)<br />[💻](https://github.com/snipe/snipe-it/commits?author=sunflowerbofh "Code") | [<img src="https://avatars.githubusercontent.com/u/1931963?v=4" width="110px;"/><br /><sub>David Sferruzza</sub>](https://david.sferruzza.fr/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=dsferruzza "Code") | [<img src="https://avatars.githubusercontent.com/u/19511639?v=4" width="110px;"/><br /><sub>Rick Nelson</sub>](https://github.com/rnelsonee)<br />[💻](https://github.com/snipe/snipe-it/commits?author=rnelsonee "Code") | [<img src="https://avatars.githubusercontent.com/u/94169344?v=4" width="110px;"/><br /><sub>BasO12</sub>](https://github.com/BasO12)<br />[💻](https://github.com/snipe/snipe-it/commits?author=BasO12 "Code") | [<img src="https://avatars.githubusercontent.com/u/111710123?v=4" width="110px;"/><br /><sub>Vautia</sub>](https://github.com/Vautia)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Vautia "Code") |
| [<img src="https://avatars.githubusercontent.com/u/28321?v=4" width="110px;"/><br /><sub>Chris Hartjes</sub>](http://www.littlehart.net/atthekeyboard)<br />[💻](https://github.com/snipe/snipe-it/commits?author=chartjes "Code") | [<img src="https://avatars.githubusercontent.com/u/2404584?v=4" width="110px;"/><br /><sub>geo-chen</sub>](https://github.com/geo-chen)<br />[💻](https://github.com/snipe/snipe-it/commits?author=geo-chen "Code") | [<img src="https://avatars.githubusercontent.com/u/6006620?v=4" width="110px;"/><br /><sub>Phan Nguyen</sub>](https://github.com/nh314)<br />[💻](https://github.com/snipe/snipe-it/commits?author=nh314 "Code") | [<img src="https://avatars.githubusercontent.com/u/115993812?v=4" width="110px;"/><br /><sub>Iisakki Jaakkola</sub>](https://github.com/StarlessNights)<br />[💻](https://github.com/snipe/snipe-it/commits?author=StarlessNights "Code") | [<img src="https://avatars.githubusercontent.com/u/22633385?v=4" width="110px;"/><br /><sub>Ikko Ashimine</sub>](https://bandism.net/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=eltociear "Code") | [<img src="https://avatars.githubusercontent.com/u/56871540?v=4" width="110px;"/><br /><sub>Lukas Fehling</sub>](https://github.com/lukasfehling)<br />[💻](https://github.com/snipe/snipe-it/commits?author=lukasfehling "Code") | [<img src="https://avatars.githubusercontent.com/u/1975990?v=4" width="110px;"/><br /><sub>Fernando Almeida</sub>](https://github.com/fernando-almeida)<br />[💻](https://github.com/snipe/snipe-it/commits?author=fernando-almeida "Code") |
| [<img src="https://avatars.githubusercontent.com/u/116301219?v=4" width="110px;"/><br /><sub>akemidx</sub>](https://github.com/akemidx)<br />[💻](https://github.com/snipe/snipe-it/commits?author=akemidx "Code") | [<img src="https://avatars.githubusercontent.com/u/144778?v=4" width="110px;"/><br /><sub>Oguz Bilgic</sub>](http://oguz.site)<br />[💻](https://github.com/snipe/snipe-it/commits?author=oguzbilgic "Code") | [<img src="https://avatars.githubusercontent.com/u/9262438?v=4" width="110px;"/><br /><sub>Scooter Crawford</sub>](https://github.com/scoo73r)<br />[💻](https://github.com/snipe/snipe-it/commits?author=scoo73r "Code") | [<img src="https://avatars.githubusercontent.com/u/5957345?v=4" width="110px;"/><br /><sub>subdriven</sub>](https://github.com/subdriven)<br />[💻](https://github.com/snipe/snipe-it/commits?author=subdriven "Code") | [<img src="https://avatars.githubusercontent.com/u/658865?v=4" width="110px;"/><br /><sub>Andrew Savinykh</sub>](https://github.com/AndrewSav)<br />[💻](https://github.com/snipe/snipe-it/commits?author=AndrewSav "Code") | [<img src="https://avatars.githubusercontent.com/u/1155067?v=4" width="110px;"/><br /><sub>Tadayuki Onishi</sub>](https://kenchan0130.github.io)<br />[💻](https://github.com/snipe/snipe-it/commits?author=kenchan0130 "Code") | [<img src="https://avatars.githubusercontent.com/u/112496896?v=4" width="110px;"/><br /><sub>Florian</sub>](https://github.com/floschoepfer)<br />[💻](https://github.com/snipe/snipe-it/commits?author=floschoepfer "Code") |
| [<img src="https://avatars.githubusercontent.com/u/7305753?v=4" width="110px;"/><br /><sub>Spencer Long</sub>](http://spencerlong.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=spencerrlongg "Code") | [<img src="https://avatars.githubusercontent.com/u/1141514?v=4" width="110px;"/><br /><sub>Marcus Moore</sub>](https://github.com/marcusmoore)<br />[💻](https://github.com/snipe/snipe-it/commits?author=marcusmoore "Code") | [<img src="https://avatars.githubusercontent.com/u/570639?v=4" width="110px;"/><br /><sub>Martin Meredith</sub>](https://github.com/Mezzle)<br /> | [<img src="https://avatars.githubusercontent.com/u/5731963?v=4" width="110px;"/><br /><sub>dboth</sub>](http://dboth.de)<br />[💻](https://github.com/snipe/snipe-it/commits?author=dboth "Code") | [<img src="https://avatars.githubusercontent.com/u/87536651?v=4" width="110px;"/><br /><sub>Zachary Fleck</sub>](https://github.com/zacharyfleck)<br />[💻](https://github.com/snipe/snipe-it/commits?author=zacharyfleck "Code") | [<img src="https://avatars.githubusercontent.com/u/74609912?v=4" width="110px;"/><br /><sub>VIKAAS-A</sub>](https://github.com/vikaas-cyper)<br />[💻](https://github.com/snipe/snipe-it/commits?author=vikaas-cyper "Code") |
| [<img src="https://avatars.githubusercontent.com/u/7305753?v=4" width="110px;"/><br /><sub>Spencer Long</sub>](http://spencerlong.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=spencerrlongg "Code") | [<img src="https://avatars.githubusercontent.com/u/1141514?v=4" width="110px;"/><br /><sub>Marcus Moore</sub>](https://github.com/marcusmoore)<br />[💻](https://github.com/snipe/snipe-it/commits?author=marcusmoore "Code") | [<img src="https://avatars.githubusercontent.com/u/570639?v=4" width="110px;"/><br /><sub>Martin Meredith</sub>](https://github.com/Mezzle)<br /> | [<img src="https://avatars.githubusercontent.com/u/5731963?v=4" width="110px;"/><br /><sub>dboth</sub>](http://dboth.de)<br />[💻](https://github.com/snipe/snipe-it/commits?author=dboth "Code") | [<img src="https://avatars.githubusercontent.com/u/87536651?v=4" width="110px;"/><br /><sub>Zachary Fleck</sub>](https://github.com/zacharyfleck)<br />[💻](https://github.com/snipe/snipe-it/commits?author=zacharyfleck "Code") | [<img src="https://avatars.githubusercontent.com/u/74609912?v=4" width="110px;"/><br /><sub>VIKAAS-A</sub>](https://github.com/vikaas-cyper)<br />[💻](https://github.com/snipe/snipe-it/commits?author=vikaas-cyper "Code") | [<img src="https://avatars.githubusercontent.com/u/88882041?v=4" width="110px;"/><br /><sub>Abdul Kareem</sub>](https://github.com/ak-piracha)<br />[💻](https://github.com/snipe/snipe-it/commits?author=ak-piracha "Code") |
| [<img src="https://avatars.githubusercontent.com/u/111287779?v=4" width="110px;"/><br /><sub>NojoudAlshehri</sub>](https://github.com/NojoudAlshehri)<br />[💻](https://github.com/snipe/snipe-it/commits?author=NojoudAlshehri "Code") | [<img src="https://avatars.githubusercontent.com/u/54367449?v=4" width="110px;"/><br /><sub>Stefan Stidl</sub>](https://github.com/stefanstidlffg)<br />[💻](https://github.com/snipe/snipe-it/commits?author=stefanstidlffg "Code") | [<img src="https://avatars.githubusercontent.com/u/87803479?v=4" width="110px;"/><br /><sub>Quentin Aymard</sub>](https://github.com/qay21)<br />[💻](https://github.com/snipe/snipe-it/commits?author=qay21 "Code") |
<!-- ALL-CONTRIBUTORS-LIST:END -->
This project follows the [all-contributors](https://github.com/kentcdodds/all-contributors) specification. Contributions of any kind welcome!

View file

@ -150,7 +150,7 @@ class AccessoriesController extends Controller
public function show($id)
{
$this->authorize('view', Accessory::class);
$accessory = Accessory::findOrFail($id);
$accessory = Accessory::withCount('users as users_count')->findOrFail($id);
return (new AccessoriesTransformer)->transformAccessory($accessory);
}

View file

@ -63,7 +63,7 @@ class AssetModelsController extends Controller
'models.deleted_at',
'models.updated_at',
])
->with('category', 'depreciation', 'manufacturer', 'fieldset')
->with('category', 'depreciation', 'manufacturer', 'fieldset.fields.defaultValues')
->withCount('assets as assets_count');
if ($request->input('status')=='deleted') {

View file

@ -403,7 +403,7 @@ class Asset extends Depreciable
*/
public function components()
{
return $this->belongsToMany('\App\Models\Component', 'components_assets', 'asset_id', 'component_id')->withPivot('id', 'assigned_qty', 'created_at')->withTrashed();
return $this->belongsToMany('\App\Models\Component', 'components_assets', 'asset_id', 'component_id')->withPivot('id', 'assigned_qty', 'created_at');
}
@ -947,8 +947,10 @@ class Asset extends Depreciable
->orWhere('assets_users.first_name', 'LIKE', '%'.$term.'%')
->orWhere('assets_users.last_name', 'LIKE', '%'.$term.'%')
->orWhere('assets_users.username', 'LIKE', '%'.$term.'%')
->orWhereRaw('CONCAT('.DB::getTablePrefix().'assets_users.first_name," ",'.DB::getTablePrefix().'assets_users.last_name) LIKE ?', ["%$term%"]);
->orWhereMultipleColumns([
'assets_users.first_name',
'assets_users.last_name',
], $term);
}
/**
@ -1343,7 +1345,10 @@ class Asset extends Depreciable
})->orWhere(function ($query) use ($search) {
$query->where('assets_users.first_name', 'LIKE', '%'.$search.'%')
->orWhere('assets_users.last_name', 'LIKE', '%'.$search.'%')
->orWhereRaw('CONCAT('.DB::getTablePrefix().'assets_users.first_name," ",'.DB::getTablePrefix().'assets_users.last_name) LIKE ?', ["%$search%"])
->orWhereMultipleColumns([
'assets_users.first_name',
'assets_users.last_name',
], $search)
->orWhere('assets_users.username', 'LIKE', '%'.$search.'%')
->orWhere('assets_locations.name', 'LIKE', '%'.$search.'%')
->orWhere('assigned_assets.name', 'LIKE', '%'.$search.'%');
@ -1662,7 +1667,7 @@ class Asset extends Depreciable
public function scopeOrderManufacturer($query, $order)
{
return $query->join('models as order_asset_model', 'assets.model_id', '=', 'order_asset_model.id')
->join('manufacturers as manufacturer_order', 'order_asset_model.manufacturer_id', '=', 'manufacturer_order.id')
->leftjoin('manufacturers as manufacturer_order', 'order_asset_model.manufacturer_id', '=', 'manufacturer_order.id')
->orderBy('manufacturer_order.name', $order);
}

View file

@ -306,9 +306,9 @@ class CustomField extends Model
$arr_parts = explode('|', $arr[$x]);
if ($arr_parts[0] != '') {
if (array_key_exists('1', $arr_parts)) {
$result[$arr_parts[0]] = $arr_parts[1];
$result[$arr_parts[0]] = trim($arr_parts[1]);
} else {
$result[$arr_parts[0]] = $arr_parts[0];
$result[$arr_parts[0]] = trim($arr_parts[0]);
}
}
}

View file

@ -5,6 +5,7 @@ namespace App\Models\Traits;
use App\Models\Asset;
use App\Models\CustomField;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\DB;
/**
* This trait allows for cleaner searching of models,
@ -164,7 +165,13 @@ trait Searchable
}
// I put this here because I only want to add the concat one time in the end of the user relation search
if($relation == 'user') {
$query->orWhereRaw('CONCAT (users.first_name, " ", users.last_name) LIKE ?', ["%{$term}%"]);
$query->orWhereRaw(
$this->buildMultipleColumnSearch([
'users.first_name',
'users.last_name',
]),
["%{$term}%"]
);
}
});
}
@ -257,4 +264,37 @@ trait Searchable
return $related->getTable();
}
/**
* Builds a search string for either MySQL or sqlite by separating the provided columns with a space.
*
* @param array $columns Columns to include in search string.
* @return string
*/
private function buildMultipleColumnSearch(array $columns): string
{
$mappedColumns = collect($columns)->map(fn($column) => DB::getTablePrefix() . $column)->toArray();
$driver = config('database.connections.' . config('database.default') . '.driver');
if ($driver === 'sqlite') {
return implode("||' '||", $mappedColumns) . ' LIKE ?';
}
// Default to MySQL's concatenation method
return 'CONCAT(' . implode('," ",', $mappedColumns) . ') LIKE ?';
}
/**
* Search a string across multiple columns separated with a space.
*
* @param Builder $query
* @param array $columns - Columns to include in search string.
* @param $term
* @return Builder
*/
public function scopeOrWhereMultipleColumns($query, array $columns, $term)
{
return $query->orWhereRaw($this->buildMultipleColumnSearch($columns), ["%{$term}%"]);
}
}

View file

@ -644,14 +644,14 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
*/
public function scopeSimpleNameSearch($query, $search)
{
$query = $query->where('first_name', 'LIKE', '%'.$search.'%')
return $query->where('first_name', 'LIKE', '%' . $search . '%')
->orWhere('last_name', 'LIKE', '%' . $search . '%')
->orWhereRaw('CONCAT('.DB::getTablePrefix().'users.first_name," ",'.DB::getTablePrefix().'users.last_name) LIKE ?', ["%{$search}%"]);
return $query;
->orWhereMultipleColumns([
'users.first_name',
'users.last_name',
], $search);
}
/**
* Run additional, advanced searches.
*
@ -660,9 +660,11 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
* @return \Illuminate\Database\Eloquent\Builder
*/
public function advancedTextSearch(Builder $query, array $terms) {
foreach($terms as $term) {
$query = $query->orWhereRaw('CONCAT('.DB::getTablePrefix().'users.first_name," ",'.DB::getTablePrefix().'users.last_name) LIKE ?', ["%{$term}%"]);
$query->orWhereMultipleColumns([
'users.first_name',
'users.last_name',
], $term);
}
return $query;

View file

@ -23,6 +23,7 @@ class AuditNotification extends Notification
public function __construct($params)
{
//
$this->settings = Setting::getSettings();
$this->params = $params;
}
@ -43,9 +44,12 @@ class AuditNotification extends Notification
public function toSlack()
{
$channel = ($this->settings->webhook_channel) ? $this->settings->webhook_channel : '';
return (new SlackMessage)
->success()
->content(class_basename(get_class($this->params['item'])).' Audited')
->from(($this->settings->webhook_botname) ? $this->settings->webhook_botname : 'Snipe-Bot')
->to($channel)
->attachment(function ($attachment) {
$item = $this->params['item'];
$admin_user = $this->params['admin'];

View file

@ -92,6 +92,7 @@ class CheckinAccessoryNotification extends Notification
$item = $this->item;
$note = $this->note;
$botname = ($this->settings->webhook_botname) ? $this->settings->webhook_botname : 'Snipe-Bot';
$channel = ($this->settings->webhook_channel) ? $this->settings->webhook_channel : '';
$fields = [
'To' => '<'.$target->present()->viewUrl().'|'.$target->present()->fullName().'>',
@ -101,6 +102,7 @@ class CheckinAccessoryNotification extends Notification
return (new SlackMessage)
->content(':arrow_down: :keyboard: '.trans('mail.Accessory_Checkin_Notification'))
->from($botname)
->to($channel)
->attachment(function ($attachment) use ($item, $note, $admin, $fields) {
$attachment->title(htmlspecialchars_decode($item->present()->name), $item->present()->viewUrl())
->fields($fields)

View file

@ -65,6 +65,7 @@ class CheckinAssetNotification extends Notification
$item = $this->item;
$note = $this->note;
$botname = ($this->settings->webhook_botname != '') ? $this->settings->webhook_botname : 'Snipe-Bot';
$channel = ($this->settings->webhook_channel) ? $this->settings->webhook_channel : '';
$fields = [
trans('general.administrator') => '<'.$admin->present()->viewUrl().'|'.$admin->present()->fullName().'>',
@ -75,6 +76,7 @@ class CheckinAssetNotification extends Notification
return (new SlackMessage)
->content(':arrow_down: :computer: '.trans('mail.Asset_Checkin_Notification'))
->from($botname)
->to($channel)
->attachment(function ($attachment) use ($item, $note, $admin, $fields) {
$attachment->title(htmlspecialchars_decode($item->present()->name), $item->present()->viewUrl())
->fields($fields)

View file

@ -63,6 +63,7 @@ class CheckinLicenseSeatNotification extends Notification
$item = $this->item;
$note = $this->note;
$botname = ($this->settings->webhook_botname) ? $this->settings->webhook_botname : 'Snipe-Bot';
$channel = ($this->settings->webhook_channel) ? $this->settings->webhook_channel : '';
if ($admin) {
$fields = [
@ -79,6 +80,7 @@ class CheckinLicenseSeatNotification extends Notification
return (new SlackMessage)
->content(':arrow_down: :floppy_disk: '.trans('mail.License_Checkin_Notification'))
->from($botname)
->to($channel)
->attachment(function ($attachment) use ($item, $note, $admin, $fields) {
$attachment->title(htmlspecialchars_decode($item->present()->name), $item->present()->viewUrl())
->fields($fields)

View file

@ -79,6 +79,7 @@ class CheckoutAccessoryNotification extends Notification
$item = $this->item;
$note = $this->note;
$botname = ($this->settings->webhook_botname) ? $this->settings->webhook_botname : 'Snipe-Bot';
$channel = ($this->settings->webhook_channel) ? $this->settings->webhook_channel : '';
$fields = [
'To' => '<'.$target->present()->viewUrl().'|'.$target->present()->fullName().'>',
@ -88,6 +89,7 @@ class CheckoutAccessoryNotification extends Notification
return (new SlackMessage)
->content(':arrow_up: :keyboard: Accessory Checked Out')
->from($botname)
->to($channel)
->attachment(function ($attachment) use ($item, $note, $admin, $fields) {
$attachment->title(htmlspecialchars_decode($item->present()->name), $item->present()->viewUrl())
->fields($fields)

View file

@ -96,6 +96,7 @@ class CheckoutAssetNotification extends Notification
$item = $this->item;
$note = $this->note;
$botname = ($this->settings->webhook_botname) ? $this->settings->webhook_botname : 'Snipe-Bot';
$channel = ($this->settings->webhook_channel) ? $this->settings->webhook_channel : '';
$fields = [
'To' => '<'.$target->present()->viewUrl().'|'.$target->present()->fullName().'>',
@ -109,6 +110,7 @@ class CheckoutAssetNotification extends Notification
return (new SlackMessage)
->content(':arrow_up: :computer: '.trans('mail.Asset_Checkout_Notification'))
->from($botname)
->to($channel)
->attachment(function ($attachment) use ($item, $note, $admin, $fields) {
$attachment->title(htmlspecialchars_decode($item->present()->name), $item->present()->viewUrl())
->fields($fields)

View file

@ -85,6 +85,7 @@ class CheckoutConsumableNotification extends Notification
$item = $this->item;
$note = $this->note;
$botname = ($this->settings->webhook_botname) ? $this->settings->webhook_botname : 'Snipe-Bot';
$channel = ($this->settings->webhook_channel) ? $this->settings->webhook_channel : '';
$fields = [
'To' => '<'.$target->present()->viewUrl().'|'.$target->present()->fullName().'>',
@ -94,6 +95,7 @@ class CheckoutConsumableNotification extends Notification
return (new SlackMessage)
->content(':arrow_up: :paperclip: Consumable Checked Out')
->from($botname)
->to($channel)
->attachment(function ($attachment) use ($item, $note, $admin, $fields) {
$attachment->title(htmlspecialchars_decode($item->present()->name), $item->present()->viewUrl())
->fields($fields)

View file

@ -85,6 +85,7 @@ class CheckoutLicenseSeatNotification extends Notification
$item = $this->item;
$note = $this->note;
$botname = ($this->settings->webhook_botname) ? $this->settings->webhook_botname : 'Snipe-Bot';
$channel = ($this->settings->webhook_channel) ? $this->settings->webhook_channel : '';
$fields = [
'To' => '<'.$target->present()->viewUrl().'|'.$target->present()->fullName().'>',
@ -94,6 +95,7 @@ class CheckoutLicenseSeatNotification extends Notification
return (new SlackMessage)
->content(':arrow_up: :floppy_disk: License Checked Out')
->from($botname)
->to($channel)
->attachment(function ($attachment) use ($item, $note, $admin, $fields) {
$attachment->title(htmlspecialchars_decode($item->present()->name), $item->present()->viewUrl())
->fields($fields)

View file

@ -74,6 +74,7 @@ class RequestAssetCancelation extends Notification
$note = $this->note;
$qty = $this->item_quantity;
$botname = ($this->settings->webhook_botname) ? $this->settings->webhook_botname : 'Snipe-Bot';
$channel = ($this->settings->webhook_channel) ? $this->settings->webhook_channel : '';
$fields = [
'QTY' => $qty,
@ -87,6 +88,7 @@ class RequestAssetCancelation extends Notification
return (new SlackMessage)
->content(trans('mail.a_user_canceled'))
->from($botname)
->to($channel)
->attachment(function ($attachment) use ($item, $note, $fields) {
$attachment->title(htmlspecialchars_decode($item->present()->name), $item->present()->viewUrl())
->fields($fields)

View file

@ -74,6 +74,7 @@ class RequestAssetNotification extends Notification
$item = $this->item;
$note = $this->note;
$botname = ($this->settings->webhook_botname) ? $this->settings->webhook_botname : 'Snipe-Bot';
$channel = ($this->settings->webhook_channel) ? $this->settings->webhook_channel : '';
$fields = [
'QTY' => $qty,
@ -83,6 +84,7 @@ class RequestAssetNotification extends Notification
return (new SlackMessage)
->content(trans('mail.Item_Requested'))
->from($botname)
->to($channel)
->attachment(function ($attachment) use ($item, $note, $fields) {
$attachment->title(htmlspecialchars_decode($item->present()->name), $item->present()->viewUrl())
->fields($fields)

View file

@ -1,11 +1,10 @@
<?php
return array (
'app_version' => 'v6.1.1-pre',
'full_app_version' => 'v6.1.1-pre - build 10653-g11cd875c6',
'build_version' => '10653',
'full_app_version' => 'v6.1.1-pre - build 10778-gfc5b02e39',
'build_version' => '10778',
'prerelease_version' => '',
'hash_version' => 'g11cd875c6',
'full_hash' => 'v6.1.1-pre-411-g11cd875c6',
'branch' => 'master',
'hash_version' => 'gfc5b02e39',
'full_hash' => 'v6.1.1-pre-536-gfc5b02e39',
'branch' => 'develop',
);

View file

@ -27,7 +27,7 @@ class ConsumableFactory extends Factory
public function definition()
{
return [
'name' => $this->faker->word(),
'name' => $this->faker->words(3, true),
'category_id' => Category::factory(),
'user_id' => User::factory()->superuser(),
'item_no' => $this->faker->numberBetween(1000000, 50000000),

View file

@ -38,22 +38,32 @@ class CustomFieldSeeder extends Seeder
[
'custom_field_id' => '1',
'custom_fieldset_id' => '1',
'order' => 0,
'required' => 0,
],
[
'custom_field_id' => '2',
'custom_fieldset_id' => '1',
'order' => 0,
'required' => 0,
],
[
'custom_field_id' => '3',
'custom_fieldset_id' => '2',
'order' => 0,
'required' => 0,
],
[
'custom_field_id' => '4',
'custom_fieldset_id' => '2',
'order' => 0,
'required' => 0,
],
[
'custom_field_id' => '5',
'custom_fieldset_id' => '2',
'order' => 0,
'required' => 0,
],
]);

35
package-lock.json generated
View file

@ -7,13 +7,13 @@
"dependencies": {
"@fortawesome/fontawesome-free": "^6.4.0",
"acorn": "^8.8.2",
"acorn-import-assertions": "^1.8.0",
"acorn-import-assertions": "^1.9.0",
"admin-lte": "^2.4.18",
"ajv": "^6.12.6",
"blueimp-file-upload": "^9.34.0",
"bootstrap": "^3.4.1",
"bootstrap-colorpicker": "^2.5.3",
"bootstrap-datepicker": "^1.9.0",
"bootstrap-datepicker": "^1.10.0",
"bootstrap-less": "^3.3.8",
"bootstrap-table": "1.21.4",
"chart.js": "^2.9.4",
@ -35,7 +35,7 @@
"tableexport.jquery.plugin": "1.27.0",
"tether": "^1.4.0",
"vue-resource": "^1.5.2",
"webpack": "^5.79.0"
"webpack": "^5.83.1"
},
"devDependencies": {
"axios": "^0.27.2",
@ -2470,8 +2470,9 @@
}
},
"node_modules/acorn-import-assertions": {
"version": "1.8.0",
"license": "MIT",
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz",
"integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==",
"peerDependencies": {
"acorn": "^8"
}
@ -3507,10 +3508,11 @@
}
},
"node_modules/bootstrap-datepicker": {
"version": "1.9.0",
"license": "Apache-2.0",
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/bootstrap-datepicker/-/bootstrap-datepicker-1.10.0.tgz",
"integrity": "sha512-lWxtSYddAQOpbAO8UhYhHLcK6425eWoSjb5JDvZU3ePHEPF6A3eUr51WKaFy4PccU19JRxUG6wEU3KdhtKfvpg==",
"dependencies": {
"jquery": ">=1.7.1 <4.0.0"
"jquery": ">=3.4.0 <4.0.0"
}
},
"node_modules/bootstrap-daterangepicker": {
@ -5193,8 +5195,9 @@
}
},
"node_modules/enhanced-resolve": {
"version": "5.13.0",
"license": "MIT",
"version": "5.14.1",
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.14.1.tgz",
"integrity": "sha512-Vklwq2vDKtl0y/vtwjSesgJ5MYS7Etuk5txS8VdKL4AOS1aUlD96zqIfsOSLQsdv3xgMRbtkWM8eG9XDfKUPow==",
"dependencies": {
"graceful-fs": "^4.2.4",
"tapable": "^2.2.0"
@ -10414,7 +10417,8 @@
},
"node_modules/tapable": {
"version": "2.2.1",
"license": "MIT",
"resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz",
"integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==",
"engines": {
"node": ">=6"
}
@ -10936,8 +10940,9 @@
}
},
"node_modules/webpack": {
"version": "5.81.0",
"license": "MIT",
"version": "5.86.0",
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.86.0.tgz",
"integrity": "sha512-3BOvworZ8SO/D4GVP+GoRC3fVeg5MO4vzmq8TJJEkdmopxyazGDxN8ClqN12uzrZW9Tv8EED8v5VSb6Sqyi0pg==",
"dependencies": {
"@types/eslint-scope": "^3.7.3",
"@types/estree": "^1.0.0",
@ -10945,10 +10950,10 @@
"@webassemblyjs/wasm-edit": "^1.11.5",
"@webassemblyjs/wasm-parser": "^1.11.5",
"acorn": "^8.7.1",
"acorn-import-assertions": "^1.7.6",
"acorn-import-assertions": "^1.9.0",
"browserslist": "^4.14.5",
"chrome-trace-event": "^1.0.2",
"enhanced-resolve": "^5.13.0",
"enhanced-resolve": "^5.14.1",
"es-module-lexer": "^1.2.1",
"eslint-scope": "5.1.1",
"events": "^3.2.0",

View file

@ -26,13 +26,13 @@
"dependencies": {
"@fortawesome/fontawesome-free": "^6.4.0",
"acorn": "^8.8.2",
"acorn-import-assertions": "^1.8.0",
"acorn-import-assertions": "^1.9.0",
"admin-lte": "^2.4.18",
"ajv": "^6.12.6",
"blueimp-file-upload": "^9.34.0",
"bootstrap": "^3.4.1",
"bootstrap-colorpicker": "^2.5.3",
"bootstrap-datepicker": "^1.9.0",
"bootstrap-datepicker": "^1.10.0",
"bootstrap-less": "^3.3.8",
"bootstrap-table": "1.21.4",
"chart.js": "^2.9.4",
@ -54,6 +54,6 @@
"tableexport.jquery.plugin": "1.27.0",
"tether": "^1.4.0",
"vue-resource": "^1.5.2",
"webpack": "^5.79.0"
"webpack": "^5.83.1"
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
public/js/dist/all.js vendored

Binary file not shown.

View file

@ -1,8 +1,8 @@
{
"/js/build/app.js": "/js/build/app.js?id=43fc984e5d0f901e04cef2474972e97f",
"/css/dist/skins/skin-blue.css": "/css/dist/skins/skin-blue.css?id=392cc93cfc0be0349bab9697669dd091",
"/css/build/overrides.css": "/css/build/overrides.css?id=c10cdb33a3fbb084fdb88edb6f5d2f2e",
"/css/build/app.css": "/css/build/app.css?id=941acd508610302404d0da2ad1471687",
"/css/build/overrides.css": "/css/build/overrides.css?id=eb013ebb79d92e25ce24b0c0b53185e4",
"/css/build/app.css": "/css/build/app.css?id=ac51a0600b419996e705675b6fcf1a8b",
"/css/build/AdminLTE.css": "/css/build/AdminLTE.css?id=a67bd93bed52e6a29967fe472de66d6c",
"/css/dist/skins/skin-orange.css": "/css/dist/skins/skin-orange.css?id=268041e902b019730c23ee3875838005",
"/css/dist/skins/skin-orange-dark.css": "/css/dist/skins/skin-orange-dark.css?id=d409d9b1a3b69247df8b98941ba06e33",
@ -18,7 +18,7 @@
"/css/dist/skins/skin-green.css": "/css/dist/skins/skin-green.css?id=b48f4d8af0e1ca5621c161e93951109f",
"/css/dist/skins/skin-contrast.css": "/css/dist/skins/skin-contrast.css?id=f0fbbb0ac729ea092578fb05ca615460",
"/css/dist/skins/skin-red.css": "/css/dist/skins/skin-red.css?id=b9a74ec0cd68f83e7480d5ae39919beb",
"/css/dist/all.css": "/css/dist/all.css?id=19dde3027f3ff4ad5bd87368095ccbd8",
"/css/dist/all.css": "/css/dist/all.css?id=15ac70d1eb588ad379df3e1911523048",
"/css/dist/signature-pad.css": "/css/dist/signature-pad.css?id=6a89d3cd901305e66ced1cf5f13147f7",
"/css/dist/signature-pad.min.css": "/css/dist/signature-pad.min.css?id=6a89d3cd901305e66ced1cf5f13147f7",
"/css/webfonts/fa-brands-400.ttf": "/css/webfonts/fa-brands-400.ttf?id=e2e2b1797606a266ed55549f5bb5a179",
@ -30,9 +30,9 @@
"/css/webfonts/fa-v4compatibility.ttf": "/css/webfonts/fa-v4compatibility.ttf?id=6ebbf5afc34f54463abc2b81ca637364",
"/css/webfonts/fa-v4compatibility.woff2": "/css/webfonts/fa-v4compatibility.woff2?id=67b8a78b7e80e805cfa4ee0421895ba4",
"/css/dist/bootstrap-table.css": "/css/dist/bootstrap-table.css?id=2265e072e44c782c901dce8e037d97fc",
"/js/build/vendor.js": "/js/build/vendor.js?id=acde5bad7a4576c457ecc68981613fd9",
"/js/build/vendor.js": "/js/build/vendor.js?id=8ac1d250496313e93744790e5138305d",
"/js/dist/bootstrap-table.js": "/js/dist/bootstrap-table.js?id=a0e44dba789031b34ef150a01318b865",
"/js/dist/all.js": "/js/dist/all.js?id=bb74b7a6af194e31e758a70ace765b2a",
"/js/dist/all.js": "/js/dist/all.js?id=b487452bd6bef7fa6201586415d383f2",
"/css/dist/skins/skin-green.min.css": "/css/dist/skins/skin-green.min.css?id=b48f4d8af0e1ca5621c161e93951109f",
"/css/dist/skins/skin-green-dark.min.css": "/css/dist/skins/skin-green-dark.min.css?id=44f9320d0739f419c9246f7f39395b02",
"/css/dist/skins/skin-black.min.css": "/css/dist/skins/skin-black.min.css?id=1f33ca3d860461c1127ec465ab3ebb6b",

View file

@ -673,6 +673,9 @@ th.css-accessory > .th-inner::before
}
@media screen and (max-width: 511px){
.tab-content .tab-pane .alert-block {
margin-top: 120px
}
.sidebar-menu{
margin-top:160px;
}
@ -842,6 +845,18 @@ input[type="radio"]:checked::before {
gap: 1.5em;
}
.container.row-striped .col-md-6 {
overflow-wrap:anywhere;
}
.nav-tabs-custom > .nav-tabs > li {
z-index: 1;
}
.select2-container .select2-search--inline .select2-search__field{
padding-left:15px;
}
/** --------------------------------------- **/
/** End checkbox styles to replace iCheck **/
/** --------------------------------------- **/

View file

@ -442,7 +442,7 @@ return [
'importer_generic_error' => 'Your file import is complete, but we did receive an error. This is usually caused by third-party API throttling from a notification webhook (such as Slack) and would not have interfered with the import itself, but you should confirm this.',
'confirm' => 'Confirm',
'autoassign_licenses' => 'Auto-Assign Licenses',
'autoassign_licenses_help' => 'Allow user to be have licenses assigned via the bulk-assign license UI or cli tools.',
'autoassign_licenses_help' => 'Allow this user to have licenses assigned via the bulk-assign license UI or cli tools.',
'autoassign_licenses_help_long' => 'This allows a user to be have licenses assigned via the bulk-assign license UI or cli tools. (For example, you might not want contractors to be auto-assigned a license you would provide to only staff members. You can still individually assign licenses to those users, but they will not be included in the Checkout License to All Users functions.)',
'no_autoassign_licenses_help' => 'Do not include user for bulk-assigning through the license UI or cli tools.',
'modal_confirm_generic' => 'Are you sure?',

View file

@ -78,7 +78,7 @@
<div class="col-md-12">
@if ($models->count() > 0)
<h2>{{ trans('general.requestable_models') }}</h4>
<h2>{{ trans('general.requestable_models') }}</h2>
<table
name="requested-assets"
data-toolbar="#toolbar"

View file

@ -3,7 +3,7 @@
{{ trans('mail.the_following_item') }}
@if ($item->getImageUrl())
@if (($snipeSettings->show_images_in_email =='1') && $item->getImageUrl())
<center><img src="{{ $item->getImageUrl() }}" alt="Asset" style="max-width: 570px;"></center>
@endif

View file

@ -30,6 +30,19 @@ class UsersForSelectListTest extends TestCase
->assertJson(fn(AssertableJson $json) => $json->has('results', 3)->etc());
}
public function testUsersCanBeSearchedByFirstAndLastName()
{
User::factory()->create(['first_name' => 'Luke', 'last_name' => 'Skywalker']);
Passport::actingAs(User::factory()->create());
$response = $this->getJson(route('api.users.selectlist', ['search' => 'luke sky']))->assertOk();
$results = collect($response->json('results'));
$this->assertEquals(1, $results->count());
$this->assertTrue($results->pluck('text')->contains(fn($text) => str_contains($text, 'Luke')));
}
public function testUsersScopedToCompanyWhenMultipleFullCompanySupportEnabled()
{
$this->settings->enableMultipleFullCompanySupport();

View file

@ -0,0 +1,28 @@
<?php
namespace Tests\Feature\Api\Users;
use App\Models\User;
use Laravel\Passport\Passport;
use Tests\Support\InteractsWithSettings;
use Tests\TestCase;
class UsersSearchTest extends TestCase
{
use InteractsWithSettings;
public function testCanSearchByUserFirstAndLastName()
{
User::factory()->create(['first_name' => 'Luke', 'last_name' => 'Skywalker']);
User::factory()->create(['first_name' => 'Darth', 'last_name' => 'Vader']);
Passport::actingAs(User::factory()->viewUsers()->create());
$response = $this->getJson(route('api.users.index', ['search' => 'luke sky']))->assertOk();
$results = collect($response->json('rows'));
$this->assertEquals(1, $results->count());
$this->assertTrue($results->pluck('name')->contains(fn($text) => str_contains($text, 'Luke')));
$this->assertFalse($results->pluck('name')->contains(fn($text) => str_contains($text, 'Darth')));
}
}