Compare commits
38 Commits
v7.0.9
...
pagination
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
276950072f | ||
|
|
52344c5574 | ||
|
|
8cfca8bff7 | ||
|
|
f400b38c9c | ||
|
|
ee589ca112 | ||
|
|
1eb16cdb02 | ||
|
|
a56f3f85f8 | ||
|
|
239824681d | ||
|
|
0ac82fbbe1 | ||
|
|
8c5a9fa38f | ||
|
|
65dcb2a9bd | ||
|
|
a0d461d3e2 | ||
|
|
eb9e276ba7 | ||
|
|
35160f88e0 | ||
|
|
0ddb447c4c | ||
|
|
e49c96a35e | ||
|
|
2d1aeca949 | ||
|
|
e06e4db4b7 | ||
|
|
51242fcbb2 | ||
|
|
99be9ddb47 | ||
|
|
be4317361d | ||
|
|
a175b6a38b | ||
|
|
431da6c903 | ||
|
|
ab6b8f520e | ||
|
|
24e58d1455 | ||
|
|
f91ad6b2db | ||
|
|
eed253bd2f | ||
|
|
b68fcf1de5 | ||
|
|
d21ebc6f0d | ||
|
|
ad818cf886 | ||
|
|
fb7d533ff7 | ||
|
|
9dd3827222 | ||
|
|
5697370dfe | ||
|
|
442903ea5e | ||
|
|
d3ab152d30 | ||
|
|
8a0afae90f | ||
|
|
c658a0fcb4 | ||
|
|
f40284c413 |
@@ -3145,6 +3145,15 @@
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "dbakan",
|
||||
"name": "Daniel Albertsen",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/4498077?v=4",
|
||||
"profile": "https://ditscheri.com",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -183,6 +183,7 @@ REPORT_TIME_LIMIT=12000
|
||||
REQUIRE_SAML=false
|
||||
API_THROTTLE_PER_MINUTE=120
|
||||
CSV_ESCAPE_FORMULAS=true
|
||||
LIVEWIRE_URL_PREFIX=null
|
||||
|
||||
# --------------------------------------------
|
||||
# OPTIONAL: HASHING
|
||||
|
||||
2
.github/workflows/codacy-analysis.yml
vendored
2
.github/workflows/codacy-analysis.yml
vendored
@@ -36,7 +36,7 @@ jobs:
|
||||
|
||||
# Execute Codacy Analysis CLI and generate a SARIF output with the security issues identified during the analysis
|
||||
- name: Run Codacy Analysis CLI
|
||||
uses: codacy/codacy-analysis-cli-action@v4.4.1
|
||||
uses: codacy/codacy-analysis-cli-action@v4.4.5
|
||||
with:
|
||||
# Check https://github.com/codacy/codacy-analysis-cli#project-token to get your project token from your Codacy repository
|
||||
# You can also omit the token and run the tools that support default configurations
|
||||
|
||||
@@ -51,7 +51,7 @@ Thanks goes to all of these wonderful people ([emoji key](https://github.com/ken
|
||||
| [<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") | [<img src="https://avatars.githubusercontent.com/u/5396871?v=4" width="110px;"/><br /><sub>Grant Le Roux</sub>](https://github.com/cram42)<br />[💻](https://github.com/snipe/snipe-it/commits?author=cram42 "Code") | [<img src="https://avatars.githubusercontent.com/u/58479551?v=4" width="110px;"/><br /><sub>Bogdan</sub>](http://@singrity)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Singrity "Code") | [<img src="https://avatars.githubusercontent.com/u/3483684?v=4" width="110px;"/><br /><sub>mmanjos</sub>](https://github.com/mmanjos)<br />[💻](https://github.com/snipe/snipe-it/commits?author=mmanjos "Code") | [<img src="https://avatars.githubusercontent.com/u/7429229?v=4" width="110px;"/><br /><sub>Abdelaziz Faki</sub>](https://azooz2014.github.io/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Azooz2014 "Code") |
|
||||
| [<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/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") |
|
||||
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
||||
|
||||
This project follows the [all-contributors](https://github.com/kentcdodds/all-contributors) specification. Contributions of any kind welcome!
|
||||
|
||||
@@ -251,6 +251,7 @@ class LdapSync extends Command
|
||||
// Creating a new user.
|
||||
$user = new User;
|
||||
$user->password = $user->noPassword();
|
||||
$user->locale = app()->getLocale();
|
||||
$user->activated = 1; // newly created users can log in by default, unless AD's UAC is in use, or an active flag is set (below)
|
||||
$item['createorupdate'] = 'created';
|
||||
}
|
||||
|
||||
105
app/Console/Commands/SendAcceptanceReminder.php
Normal file
105
app/Console/Commands/SendAcceptanceReminder.php
Normal file
@@ -0,0 +1,105 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\Asset;
|
||||
use App\Models\CheckoutAcceptance;
|
||||
use App\Models\Setting;
|
||||
use App\Models\User;
|
||||
use App\Notifications\CheckoutAssetNotification;
|
||||
use App\Notifications\CurrentInventory;
|
||||
use App\Notifications\UnacceptedAssetReminderNotification;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Notification;
|
||||
|
||||
class SendAcceptanceReminder extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'snipeit:acceptance-reminder';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'This will resend users with unaccepted assets a reminder to accept or decline them.';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$pending = CheckoutAcceptance::pending()->where('checkoutable_type', 'App\Models\Asset')
|
||||
->whereHas('checkoutable', function($query) {
|
||||
$query->where('archived', 0);
|
||||
})
|
||||
->with(['assignedTo', 'checkoutable.assignedTo', 'checkoutable.model', 'checkoutable.adminuser'])
|
||||
->get();
|
||||
|
||||
$count = 0;
|
||||
$unacceptedAssetGroups = $pending
|
||||
->filter(function($acceptance) {
|
||||
return $acceptance->checkoutable_type == 'App\Models\Asset';
|
||||
})
|
||||
->map(function($acceptance) {
|
||||
return ['assetItem' => $acceptance->checkoutable, 'acceptance' => $acceptance];
|
||||
})
|
||||
->groupBy(function($item) {
|
||||
return $item['acceptance']->assignedTo ? $item['acceptance']->assignedTo->id : '';
|
||||
});
|
||||
|
||||
$no_mail_address = [];
|
||||
|
||||
foreach($unacceptedAssetGroups as $unacceptedAssetGroup) {
|
||||
$item_count = $unacceptedAssetGroup->count();
|
||||
foreach ($unacceptedAssetGroup as $unacceptedAsset) {
|
||||
// if ($unacceptedAsset['acceptance']->assignedTo->email == ''){
|
||||
// $no_mail_address[] = $unacceptedAsset['checkoutable']->assignedTo->present()->fullName;
|
||||
// }
|
||||
if ($unacceptedAsset['acceptance']->assignedTo) {
|
||||
|
||||
if (!$unacceptedAsset['acceptance']->assignedTo->locale) {
|
||||
Notification::locale(Setting::getSettings()->locale)->send(
|
||||
$unacceptedAsset['acceptance']->assignedTo,
|
||||
new UnacceptedAssetReminderNotification($unacceptedAsset['assetItem'], $count)
|
||||
);
|
||||
} else {
|
||||
Notification::send(
|
||||
$unacceptedAsset['acceptance']->assignedTo,
|
||||
new UnacceptedAssetReminderNotification($unacceptedAsset, $item_count)
|
||||
);
|
||||
}
|
||||
$count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($no_mail_address)) {
|
||||
foreach($no_mail_address as $user) {
|
||||
return $user.' has no email.';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
$this->info($count.' users notified.');
|
||||
}
|
||||
}
|
||||
@@ -4,22 +4,37 @@ namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Helpers\Helper;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Transformers\CategoriesTransformer;
|
||||
use App\Http\Transformers\SelectlistTransformer;
|
||||
use App\Models\Category;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use App\Http\Requests\ImageUploadRequest;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use App\Models\Traits\ApiResponder;
|
||||
use App\Http\Serializers\BootstrapTablesSerializer;
|
||||
use League\Fractal\Resource\Item;
|
||||
use League\Fractal\Resource\Collection;
|
||||
use League\Fractal\Serializer\DataArraySerializer;
|
||||
use League\Fractal\Serializer\ArraySerializer;
|
||||
use App\Http\Transformers\CategoriesTransformer;
|
||||
use League\Fractal\Manager;
|
||||
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
||||
use Spatie\Fractalistic\Fractal;
|
||||
use function Illuminate\Events\queueable;
|
||||
|
||||
|
||||
|
||||
class CategoriesController extends Controller
|
||||
{
|
||||
use ApiResponder;
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @return \Illuminate\Http\Response
|
||||
|
||||
*/
|
||||
public function index(Request $request) : array
|
||||
{
|
||||
@@ -91,18 +106,20 @@ class CategoriesController extends Controller
|
||||
$categories->where('checkin_email', '=', $request->input('checkin_email'));
|
||||
}
|
||||
|
||||
// Make sure the offset and limit are actually integers and do not exceed system limits
|
||||
$offset = ($request->input('offset') > $categories->count()) ? $categories->count() : app('api_offset_value');
|
||||
$limit = app('api_limit_value');
|
||||
|
||||
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
|
||||
$sort = in_array($request->input('sort'), $allowed_columns) ? $request->input('sort') : 'assets_count';
|
||||
$categories->orderBy($sort, $order);
|
||||
|
||||
$total = $categories->count();
|
||||
$categories = $categories->skip($offset)->take($limit)->get();
|
||||
$paginator = $categories->paginate(app('page_number'));
|
||||
$total_results = $paginator->total();
|
||||
$results = $paginator->getCollection();
|
||||
|
||||
return (new CategoriesTransformer)->transformCategories($categories, $total);
|
||||
return Fractal::create()
|
||||
->collection($results, new CategoriesTransformer())
|
||||
->serializeWith(new BootstrapTablesSerializer())
|
||||
->addMeta(['total' => $total_results])
|
||||
->paginateWith(new IlluminatePaginatorAdapter($paginator))
|
||||
->toArray();
|
||||
|
||||
}
|
||||
|
||||
@@ -141,7 +158,8 @@ class CategoriesController extends Controller
|
||||
{
|
||||
$this->authorize('view', Category::class);
|
||||
$category = Category::withCount('assets as assets_count', 'accessories as accessories_count', 'consumables as consumables_count', 'components as components_count', 'licenses as licenses_count')->findOrFail($id);
|
||||
return (new CategoriesTransformer)->transformCategory($category);
|
||||
$transformer = $category->first()->transformer;
|
||||
return $this->transformData($category, $transformer);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -475,7 +475,7 @@ class AssetsController extends Controller
|
||||
* @param int $assetId
|
||||
* @since [v1.0]
|
||||
*/
|
||||
public function getQrCode($assetId = null) : Response | BinaryFileResponse
|
||||
public function getQrCode($assetId = null) : Response | BinaryFileResponse | string | bool
|
||||
{
|
||||
$settings = Setting::getSettings();
|
||||
|
||||
@@ -502,6 +502,7 @@ class AssetsController extends Controller
|
||||
|
||||
return 'That asset is invalid';
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -378,7 +378,7 @@ class ReportsController extends Controller
|
||||
|
||||
|
||||
$csv = implode("\n", $rows);
|
||||
$response = Response::make($csv, 200);
|
||||
$response = response()->make($csv, 200);
|
||||
$response->header('Content-Type', 'text/csv');
|
||||
$response->header('Content-disposition', 'attachment;filename=report.csv');
|
||||
|
||||
@@ -1069,7 +1069,7 @@ class ReportsController extends Controller
|
||||
|
||||
// spit out a csv
|
||||
$csv = implode("\n", $rows);
|
||||
$response = Response::make($csv, 200);
|
||||
$response = response()->make($csv, 200);
|
||||
$response->header('Content-Type', 'text/csv');
|
||||
$response->header('Content-disposition', 'attachment;filename=report.csv');
|
||||
|
||||
@@ -1249,7 +1249,7 @@ class ReportsController extends Controller
|
||||
|
||||
// spit out a csv
|
||||
$csv = implode("\n", $rows);
|
||||
$response = Response::make($csv, 200);
|
||||
$response = response()->make($csv, 200);
|
||||
$response->header('Content-Type', 'text/csv');
|
||||
$response->header('Content-disposition', 'attachment;filename=report.csv');
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ class CheckLocale
|
||||
|
||||
}
|
||||
|
||||
\App::setLocale(Helper::mapLegacyLocale($language));
|
||||
app()->setLocale(Helper::mapLegacyLocale($language));
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
|
||||
30
app/Http/Serializers/BootstrapTablesSerializer.php
Normal file
30
app/Http/Serializers/BootstrapTablesSerializer.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Serializers;
|
||||
|
||||
use League\Fractal\Pagination\CursorInterface;
|
||||
use League\Fractal\Serializer\SerializerAbstract;
|
||||
use League\Fractal\Resource\ResourceInterface;
|
||||
use League\Fractal\Pagination\PaginatorInterface;
|
||||
use League\Fractal\Serializer\ArraySerializer;
|
||||
use League\Fractal\Serializer\JsonApiSerializer;
|
||||
|
||||
class BootstrapTablesSerializer extends JsonApiSerializer
|
||||
{
|
||||
public function collection($resourceKey, array $data): array
|
||||
{
|
||||
return [
|
||||
'total' => count($data),
|
||||
'rows' => $data
|
||||
];
|
||||
}
|
||||
|
||||
public function item($resourceKey, array $data): array
|
||||
{
|
||||
if ($resourceKey) {
|
||||
return [$resourceKey => $data];
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -7,20 +7,11 @@ use App\Models\Category;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use League\Fractal\TransformerAbstract;
|
||||
|
||||
class CategoriesTransformer
|
||||
class CategoriesTransformer extends TransformerAbstract
|
||||
{
|
||||
public function transformCategories(Collection $categorys, $total)
|
||||
{
|
||||
$array = [];
|
||||
foreach ($categorys as $category) {
|
||||
$array[] = self::transformCategory($category);
|
||||
}
|
||||
|
||||
return (new DatatablesTransformer)->transformDatatables($array, $total);
|
||||
}
|
||||
|
||||
public function transformCategory(Category $category = null)
|
||||
public function transform(Category $category = null)
|
||||
{
|
||||
|
||||
// We only ever use item_count for categories in this transformer, so it makes sense to keep it
|
||||
@@ -76,4 +67,6 @@ class CategoriesTransformer
|
||||
return $array;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
namespace App\Http\Transformers;
|
||||
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
|
||||
class DatatablesTransformer
|
||||
{
|
||||
public function transformDatatables($objects, $total = null)
|
||||
|
||||
@@ -11,6 +11,8 @@ use Illuminate\Support\Facades\Gate;
|
||||
use Watson\Validating\ValidatingTrait;
|
||||
use App\Helpers\Helper;
|
||||
use Illuminate\Support\Str;
|
||||
use App\Http\Transformers\CategoriesTransformer;
|
||||
use App\Presenters\CategoryPresenter;
|
||||
|
||||
/**
|
||||
* Model for Categories. Categories are a higher-level group
|
||||
@@ -24,7 +26,9 @@ class Category extends SnipeModel
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $presenter = \App\Presenters\CategoryPresenter::class;
|
||||
protected $presenter = CategoryPresenter::class;
|
||||
public $transformer = CategoriesTransformer::class;
|
||||
|
||||
use Presentable;
|
||||
use SoftDeletes;
|
||||
|
||||
|
||||
@@ -229,6 +229,7 @@ class Ldap extends Model
|
||||
$item['department'] = $ldapattributes[$ldap_result_dept][0] ?? '';
|
||||
$item['manager'] = $ldapattributes[$ldap_result_manager][0] ?? '';
|
||||
$item['location'] = $ldapattributes[$ldap_result_location][0] ?? '';
|
||||
$item['locale'] = app()->getLocale();
|
||||
|
||||
return $item;
|
||||
}
|
||||
@@ -239,7 +240,7 @@ class Ldap extends Model
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v3.0]
|
||||
* @param $ldapatttibutes
|
||||
* @return array|bool
|
||||
* @return User | bool
|
||||
*/
|
||||
public static function createUserFromLdap($ldapatttibutes, $password)
|
||||
{
|
||||
@@ -252,6 +253,7 @@ class Ldap extends Model
|
||||
$user->last_name = $item['lastname'];
|
||||
$user->username = $item['username'];
|
||||
$user->email = $item['email'];
|
||||
$user->locale = $item['locale'];
|
||||
$user->password = $user->noPassword();
|
||||
|
||||
if (Setting::getSettings()->ldap_pw_sync == '1') {
|
||||
|
||||
11
app/Models/Traits/ApiResponder.php
Normal file
11
app/Models/Traits/ApiResponder.php
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Traits;
|
||||
trait ApiResponder
|
||||
{
|
||||
protected function transformData($data, $transformer)
|
||||
{
|
||||
$transformation = fractal($data, new $transformer);
|
||||
return $transformation->toArray();
|
||||
}
|
||||
}
|
||||
73
app/Notifications/UnacceptedAssetReminderNotification.php
Normal file
73
app/Notifications/UnacceptedAssetReminderNotification.php
Normal file
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
namespace App\Notifications;
|
||||
|
||||
use App\Models\Asset;
|
||||
use App\Models\User;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Notifications\Messages\MailMessage;
|
||||
use Illuminate\Notifications\Notification;
|
||||
|
||||
class UnacceptedAssetReminderNotification extends Notification
|
||||
{
|
||||
use Queueable;
|
||||
|
||||
/**
|
||||
* Create a new notification instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($checkout_info, $count)
|
||||
{
|
||||
$this->count = $count;
|
||||
$this->target = $checkout_info['acceptance']->assignedTo;
|
||||
$this->acceptance = $checkout_info['acceptance'];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the notification's delivery channels.
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
* @return array
|
||||
*/
|
||||
public function via()
|
||||
{
|
||||
return ['mail'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the mail representation of the notification.
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
* @return \Illuminate\Notifications\Messages\MailMessage
|
||||
*/
|
||||
public function toMail()
|
||||
{
|
||||
$accept_url = route('account.accept');
|
||||
$message = (new MailMessage)->markdown('notifications.markdown.asset-reminder',
|
||||
[
|
||||
'count' => $this->count,
|
||||
'assigned_to' => $this->target->present()->fullName,
|
||||
'link' => route('account.accept'),
|
||||
'accept_url' => $accept_url,
|
||||
])
|
||||
->subject(trans('mail.unaccepted_asset_reminder'));
|
||||
|
||||
return $message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the array representation of the notification.
|
||||
*
|
||||
* @param mixed $notifiable
|
||||
* @return array
|
||||
*/
|
||||
public function toArray($notifiable)
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
}
|
||||
32
app/Providers/LivewireServiceProvider.php
Normal file
32
app/Providers/LivewireServiceProvider.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Livewire\Livewire;
|
||||
|
||||
class LivewireServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Register services.
|
||||
*/
|
||||
public function register(): void
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Bootstrap services.
|
||||
*/
|
||||
public function boot(): void
|
||||
{
|
||||
Livewire::setUpdateRoute(function ($handle) {
|
||||
return Route::post('/' . config('livewire.url_prefix') . '/livewire/update', $handle);
|
||||
});
|
||||
|
||||
Livewire::setScriptRoute(function ($handle) {
|
||||
return Route::get('/' . config('livewire.url_prefix') . '/livewire/livewire.js', $handle);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -48,6 +48,24 @@ class SettingsServiceProvider extends ServiceProvider
|
||||
return $offset;
|
||||
});
|
||||
|
||||
// Make sure the offset is actually set and is an integer
|
||||
\App::singleton('page_number', function ($results) {
|
||||
|
||||
if (request('page_number')) {
|
||||
return (int) request('page_number');
|
||||
}
|
||||
|
||||
$offset = app('api_offset_value');
|
||||
\Log::error('offset is: '.$offset);
|
||||
|
||||
$limit = app('api_limit_value');
|
||||
\Log::error('limit is: '.$limit);
|
||||
|
||||
$page_number = (intval($offset / $limit) + 1);
|
||||
\Log::error('page number is: '.$page_number);
|
||||
return $page_number;
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Set some common variables so that they're globally available.
|
||||
|
||||
@@ -62,6 +62,7 @@
|
||||
"pragmarx/google2fa-laravel": "^1.3",
|
||||
"rollbar/rollbar-laravel": "^8.0",
|
||||
"spatie/laravel-backup": "^8.8",
|
||||
"spatie/laravel-fractal": "^6.2",
|
||||
"spatie/laravel-ignition": "^2.0",
|
||||
"tecnickcom/tc-lib-barcode": "^1.15",
|
||||
"tecnickcom/tcpdf": "^6.5",
|
||||
|
||||
214
composer.lock
generated
214
composer.lock
generated
@@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "51e716db4ccd70bf942062789f7303ad",
|
||||
"content-hash": "26ebaa5d840f6fdffd729c34ce0890d3",
|
||||
"packages": [
|
||||
{
|
||||
"name": "alek13/slack",
|
||||
@@ -4058,6 +4058,76 @@
|
||||
},
|
||||
"time": "2024-05-06T20:05:52+00:00"
|
||||
},
|
||||
{
|
||||
"name": "league/fractal",
|
||||
"version": "0.20.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/thephpleague/fractal.git",
|
||||
"reference": "8b9d39b67624db9195c06f9c1ffd0355151eaf62"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/thephpleague/fractal/zipball/8b9d39b67624db9195c06f9c1ffd0355151eaf62",
|
||||
"reference": "8b9d39b67624db9195c06f9c1ffd0355151eaf62",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/orm": "^2.5",
|
||||
"illuminate/contracts": "~5.0",
|
||||
"mockery/mockery": "^1.3",
|
||||
"pagerfanta/pagerfanta": "~1.0.0",
|
||||
"phpstan/phpstan": "^1.4",
|
||||
"phpunit/phpunit": "^9.5",
|
||||
"squizlabs/php_codesniffer": "~3.4",
|
||||
"vimeo/psalm": "^4.22",
|
||||
"zendframework/zend-paginator": "~2.3"
|
||||
},
|
||||
"suggest": {
|
||||
"illuminate/pagination": "The Illuminate Pagination component.",
|
||||
"pagerfanta/pagerfanta": "Pagerfanta Paginator",
|
||||
"zendframework/zend-paginator": "Zend Framework Paginator"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "0.20.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"League\\Fractal\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Phil Sturgeon",
|
||||
"email": "me@philsturgeon.uk",
|
||||
"homepage": "http://philsturgeon.uk/",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "Handle the output of complex data structures ready for API output.",
|
||||
"homepage": "http://fractal.thephpleague.com/",
|
||||
"keywords": [
|
||||
"api",
|
||||
"json",
|
||||
"league",
|
||||
"rest"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/thephpleague/fractal/issues",
|
||||
"source": "https://github.com/thephpleague/fractal/tree/0.20.1"
|
||||
},
|
||||
"time": "2022-04-11T12:47:17+00:00"
|
||||
},
|
||||
{
|
||||
"name": "league/mime-type-detection",
|
||||
"version": "1.15.0",
|
||||
@@ -8071,6 +8141,67 @@
|
||||
],
|
||||
"time": "2024-06-12T14:39:14+00:00"
|
||||
},
|
||||
{
|
||||
"name": "spatie/fractalistic",
|
||||
"version": "2.9.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/spatie/fractalistic.git",
|
||||
"reference": "6f12686a03d035f4558d166989c62aa93bde2151"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/spatie/fractalistic/zipball/6f12686a03d035f4558d166989c62aa93bde2151",
|
||||
"reference": "6f12686a03d035f4558d166989c62aa93bde2151",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"league/fractal": "^0.20.1",
|
||||
"php": "^7.4|^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"illuminate/pagination": "~5.3.0|~5.4.0",
|
||||
"phpunit/phpunit": "^9.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Spatie\\Fractalistic\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Freek Van der Herten",
|
||||
"email": "freek@spatie.be",
|
||||
"homepage": "https://spatie.be",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "A developer friendly wrapper around Fractal",
|
||||
"homepage": "https://github.com/spatie/fractalistic",
|
||||
"keywords": [
|
||||
"api",
|
||||
"fractal",
|
||||
"fractalistic",
|
||||
"spatie",
|
||||
"transform"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/spatie/fractalistic/issues",
|
||||
"source": "https://github.com/spatie/fractalistic/tree/2.9.5"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/spatie",
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2022-04-21T12:26:22+00:00"
|
||||
},
|
||||
{
|
||||
"name": "spatie/ignition",
|
||||
"version": "1.15.0",
|
||||
@@ -8253,6 +8384,87 @@
|
||||
],
|
||||
"time": "2024-06-04T11:31:33+00:00"
|
||||
},
|
||||
{
|
||||
"name": "spatie/laravel-fractal",
|
||||
"version": "6.2.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/spatie/laravel-fractal.git",
|
||||
"reference": "0a30630d2ab49590af118172c03c99c0d838dab1"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/spatie/laravel-fractal/zipball/0a30630d2ab49590af118172c03c99c0d838dab1",
|
||||
"reference": "0a30630d2ab49590af118172c03c99c0d838dab1",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"illuminate/contracts": "^8.0|^9.0|^10.0|^11.0",
|
||||
"illuminate/support": "^8.0|^9.0|^10.0|^11.0",
|
||||
"league/fractal": "^0.20.1|^0.20",
|
||||
"nesbot/carbon": "^2.63|^3.0",
|
||||
"php": "^8.0",
|
||||
"spatie/fractalistic": "^2.9.5|^2.9",
|
||||
"spatie/laravel-package-tools": "^1.11"
|
||||
},
|
||||
"require-dev": {
|
||||
"ext-json": "*",
|
||||
"orchestra/testbench": "^7.0|^8.0|^9.0",
|
||||
"pestphp/pest": "^1.22|^2.34"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Spatie\\Fractal\\FractalServiceProvider"
|
||||
],
|
||||
"aliases": {
|
||||
"Fractal": "Spatie\\Fractal\\Facades\\Fractal"
|
||||
}
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"src/helpers.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Spatie\\Fractal\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Freek Van der Herten",
|
||||
"email": "freek@spatie.be",
|
||||
"homepage": "https://spatie.be",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "An easy to use Fractal integration for Laravel applications",
|
||||
"homepage": "https://github.com/spatie/laravel-fractal",
|
||||
"keywords": [
|
||||
"api",
|
||||
"fractal",
|
||||
"laravel",
|
||||
"laravel-fractal",
|
||||
"lumen",
|
||||
"spatie",
|
||||
"transform"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/spatie/laravel-fractal/tree/6.2.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://spatie.be/open-source/support-us",
|
||||
"type": "custom"
|
||||
}
|
||||
],
|
||||
"time": "2024-06-04T09:33:08+00:00"
|
||||
},
|
||||
{
|
||||
"name": "spatie/laravel-ignition",
|
||||
"version": "2.8.0",
|
||||
|
||||
@@ -311,8 +311,9 @@ return [
|
||||
App\Providers\ValidationServiceProvider::class,
|
||||
|
||||
/*
|
||||
* Custom service provider
|
||||
* Custom Service Providers...
|
||||
*/
|
||||
App\Providers\LivewireServiceProvider::class,
|
||||
App\Providers\MacroServiceProvider::class,
|
||||
App\Providers\SamlServiceProvider::class,
|
||||
|
||||
|
||||
@@ -157,4 +157,21 @@ return [
|
||||
*/
|
||||
|
||||
'pagination_theme' => 'tailwind',
|
||||
|
||||
/*
|
||||
|---------------------------------------------------------------------------
|
||||
| URL Prefix
|
||||
|---------------------------------------------------------------------------
|
||||
|
|
||||
| By default, Livewire sends network requests to {app.com}/livewire/update
|
||||
| while javascript assets are served via {app.com}/livewire/livewire.js
|
||||
| If you need to adjust the prefix of those urls you can do it below.
|
||||
|
|
||||
| Defining a prefix will result in the following url
|
||||
| {app.com}/{prefix}/livewire/{update|livewire.js}
|
||||
| Note: do not include the leading or trailing /
|
||||
|
|
||||
*/
|
||||
|
||||
'url_prefix' => env('LIVEWIRE_URL_PREFIX', null),
|
||||
];
|
||||
|
||||
@@ -56,6 +56,7 @@ return [
|
||||
'i_have_read' => 'I have read and agree to the terms of use, and have received this item.',
|
||||
'inventory_report' => 'Inventory Report',
|
||||
'item' => 'Item:',
|
||||
'item_checked_reminder' => 'This is a reminder that you currently have :count items checked out to you that you have not accepted or declined. Please click the link below to confirm your decision.',
|
||||
'license_expiring_alert' => 'There is :count license expiring in the next :threshold days.|There are :count licenses expiring in the next :threshold days.',
|
||||
'link_to_update_password' => 'Please click on the following link to update your :web password:',
|
||||
'login' => 'Login:',
|
||||
@@ -86,6 +87,7 @@ return [
|
||||
'upcoming-audits' => 'There is :count asset that is coming up for audit within :threshold days.|There are :count assets that are coming up for audit within :threshold days.',
|
||||
'user' => 'User',
|
||||
'username' => 'Username',
|
||||
'unaccepted_asset_reminder' => 'You have Unaccepted Assets.',
|
||||
'welcome' => 'Welcome :name',
|
||||
'welcome_to' => 'Welcome to :web!',
|
||||
'your_assets' => 'View Your Assets',
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
<!-- AssetModel name -->
|
||||
<div class="form-group">
|
||||
<label for="model" class="col-md-3 control-label">
|
||||
{{ trans('general.company') }}
|
||||
{{ trans('admin/hardware/form.model') }}
|
||||
</label>
|
||||
<div class="col-md-8">
|
||||
<p class="form-control-static">
|
||||
|
||||
@@ -32,14 +32,27 @@
|
||||
@endif
|
||||
|
||||
@if ($clients->count() > 0)
|
||||
<table class="table table-striped snipe-table">
|
||||
<table data-cookie-id-table="OAuthClientsTable"
|
||||
data-pagination="true"
|
||||
data-id-table="OAuthClientsTable"
|
||||
data-side-pagination="client"
|
||||
data-sort-order="desc"
|
||||
data-sort-name="created_at"
|
||||
id="OAuthClientsTable"
|
||||
class="table table-striped snipe-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ trans('general.id') }}</th>
|
||||
<th>{{ trans('general.name') }}</th>
|
||||
<th>{{ trans('admin/settings/general.oauth_redirect_url') }}</th>
|
||||
<th>{{ trans('admin/settings/general.oauth_secret') }}</th>
|
||||
<th><span class="sr-only">{{ trans('general.actions') }}</span></th>
|
||||
<th data-sortable="true">{{ trans('general.name') }}</th>
|
||||
<th data-sortable="true">{{ trans('admin/settings/general.oauth_redirect_url') }}</th>
|
||||
<th data-sortable="true">{{ trans('admin/settings/general.oauth_secret') }}</th>
|
||||
<th data-sortable="true">{{ trans('general.created_at') }}</th>
|
||||
<th data-sortable="true">{{ trans('general.updated_at') }}</th>
|
||||
<th>
|
||||
<span class="sr-only">
|
||||
{{ trans('general.actions') }}
|
||||
</span>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@@ -57,7 +70,7 @@
|
||||
|
||||
<!-- Redirect -->
|
||||
<td>
|
||||
{{ $client->redirect }}
|
||||
<code>{{ $client->redirect }}</code>
|
||||
</td>
|
||||
|
||||
<!-- Secret -->
|
||||
@@ -65,20 +78,33 @@
|
||||
<code>{{ $client->secret }}</code>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
{{ $client->created_at ? Helper::getFormattedDateObject($client->created_at, 'datetime', false) : '' }}
|
||||
</td>
|
||||
|
||||
<td>
|
||||
@if ($client->created_at != $client->updated_at)
|
||||
{{ $client->updated_at ? Helper::getFormattedDateObject($client->updated_at, 'datetime', false) : '' }}
|
||||
@endif
|
||||
</td>
|
||||
|
||||
<!-- Edit / Delete Button -->
|
||||
<td class="text-right">
|
||||
|
||||
<a class="action-link btn btn-sm btn-warning"
|
||||
wire:click="editClient('{{ $client->id }}')"
|
||||
onclick="$('#modal-edit-client').modal('show');">
|
||||
<i class="fas fa-pencil-alt" aria-hidden="true"></i><span class="sr-only">{{ trans('general.update') }}</span>
|
||||
<i class="fas fa-pencil-alt" aria-hidden="true"></i>
|
||||
<span class="sr-only">
|
||||
{{ trans('general.update') }}
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<a class="action-link btn btn-danger btn-sm" wire:click="deleteClient('{{ $client->id }}')">
|
||||
<i class="fas fa-trash" aria-hidden="true"></i>
|
||||
<span class="sr-only">
|
||||
{{ trans('general.delete') }}
|
||||
</span>
|
||||
{{ trans('general.delete') }}
|
||||
</span>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -96,19 +122,34 @@
|
||||
<div>
|
||||
<div class="box box-default">
|
||||
<div class="box-header">
|
||||
<h2>
|
||||
<h2 class="box-title">
|
||||
{{ trans('admin/settings/general.oauth_authorized_apps') }}
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<div class="box-body">
|
||||
<!-- Authorized Tokens -->
|
||||
<table class="table table-striped snipe-table">
|
||||
<table data-cookie-id-table="AuthorizedAppsTable"
|
||||
data-pagination="true"
|
||||
data-id-table="AuthorizedAppsTable"
|
||||
data-toolbar="#AuthorizedAppsToolbar"
|
||||
data-side-pagination="client"
|
||||
data-sort-order="desc"
|
||||
data-sort-name="created_at"
|
||||
id="AuthorizedAppsTable"
|
||||
class="table table-striped snipe-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ trans('general.name') }}</th>
|
||||
<th>{{ trans('admin/settings/general.oauth_scopes') }}</th>
|
||||
<th></th>
|
||||
<th data-sortable="true">{{ trans('general.name') }}</th>
|
||||
<th data-sortable="true"> {{ trans('account/general.personal_access_token') }}</th>
|
||||
<th data-sortable="true">{{ trans('admin/settings/general.oauth_scopes') }}</th>
|
||||
<th data-sortable="true">{{ trans('general.created_at') }}</th>
|
||||
<th data-sortable="true">{{ trans('general.expires') }}</th>
|
||||
<th>
|
||||
<span class="sr-only">
|
||||
{{ trans('general.actions') }}
|
||||
</span>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
@@ -120,6 +161,10 @@
|
||||
{{ $token->client->name }}
|
||||
</td>
|
||||
|
||||
<td>
|
||||
{{ $token->name }}
|
||||
</td>
|
||||
|
||||
<!-- Scopes -->
|
||||
<td>
|
||||
@if(!$token->scopes)
|
||||
@@ -129,6 +174,13 @@
|
||||
@endif
|
||||
</td>
|
||||
|
||||
<td>
|
||||
{{ $token->created_at ? Helper::getFormattedDateObject($token->created_at, 'datetime', false) : '' }}
|
||||
</td>
|
||||
|
||||
<td>
|
||||
{{ $token->expires_at ? Helper::getFormattedDateObject($token->expires_at, 'datetime', false) : '' }}
|
||||
</td>
|
||||
<!-- Revoke Button -->
|
||||
<td>
|
||||
<a class="btn btn-sm btn-danger pull-right"
|
||||
@@ -354,4 +406,8 @@
|
||||
</script>
|
||||
</div>
|
||||
|
||||
@section('moar_scripts')
|
||||
@include ('partials.bootstrap-table')
|
||||
@endsection
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
@component('mail::message')
|
||||
# {{ trans('mail.hello') }} {{ $assigned_to}},
|
||||
|
||||
{{trans('mail.item_checked_reminder', ['count' => $count])}}
|
||||
[{{ trans('general.click_here')}}]({{$accept_url}})
|
||||
|
||||
{{ trans('mail.best_regards') }}
|
||||
|
||||
{{ $snipeSettings->site_name }}
|
||||
|
||||
@endcomponent
|
||||
@@ -432,7 +432,7 @@
|
||||
if ((row.available_actions.checkout === true) && (row.user_can_checkout === true) && ((!row.asset_id) && (!row.assigned_to))) {
|
||||
return '<a href="{{ config('app.url') }}/licenses/' + row.license_id + '/checkout/'+row.id+'" class="btn btn-sm bg-maroon" data-tooltip="true" title="{{ trans('general.checkout_tooltip') }}">{{ trans('general.checkout') }}</a>';
|
||||
} else {
|
||||
return '<a href="{{ config('app.url') }}/licenses/' + row.id + '/checkin" class="btn btn-sm bg-purple" data-tooltip="true" title="Check in this license seat.">{{ trans('general.checkin') }}</a>';
|
||||
return '<a href="{{ config('app.url') }}/licenses/' + row.id + '/checkin" class="btn btn-sm bg-purple" data-tooltip="true" title="{{ trans('general.checkin_tooltip') }}">{{ trans('general.checkin') }}</a>';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -33,7 +33,6 @@
|
||||
size: A4;
|
||||
}
|
||||
|
||||
|
||||
.print-logo {
|
||||
max-height: 40px;
|
||||
}
|
||||
@@ -42,8 +41,6 @@
|
||||
margin-top: 20px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
|
||||
<script nonce="{{ csrf_token() }}">
|
||||
@@ -80,7 +77,10 @@
|
||||
{{ ($show_user->employee_num!='') ? ' (#'.$show_user->employee_num.') ' : '' }}
|
||||
{{ ($show_user->jobtitle!='' ? ' - '.$show_user->jobtitle : '') }}
|
||||
</h3>
|
||||
<p></p>{{ trans('admin/users/general.all_assigned_list_generation')}} {{ Helper::getFormattedDateObject(now(), 'datetime', false) }}</body>
|
||||
<p></p>{{ trans('admin/users/general.all_assigned_list_generation')}} {{ Helper::getFormattedDateObject(now(), 'datetime', false) }}
|
||||
|
||||
</body>
|
||||
|
||||
@if ($assets->count() > 0)
|
||||
@php
|
||||
$counter = 1;
|
||||
@@ -120,7 +120,9 @@
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach ($assets as $asset)
|
||||
|
||||
@php
|
||||
if ($asset->model->category->getEula()) $eulas[] = $asset->model->category->getEula()
|
||||
@endphp
|
||||
<tr>
|
||||
<td>{{ $counter }}</td>
|
||||
<td>
|
||||
@@ -148,7 +150,6 @@
|
||||
$assignedCounter = 1;
|
||||
@endphp
|
||||
@foreach ($asset->assignedAssets as $asset)
|
||||
|
||||
<tr>
|
||||
<td>{{ $counter }}.{{ $assignedCounter }}</td>
|
||||
<td>
|
||||
@@ -216,7 +217,9 @@
|
||||
@endphp
|
||||
|
||||
@foreach ($licenses as $license)
|
||||
|
||||
@php
|
||||
if ($license->category->getEula()) $eulas[] = $license->category->getEula()
|
||||
@endphp
|
||||
<tr>
|
||||
<td>{{ $lcounter }}</td>
|
||||
<td>{{ $license->name }}</td>
|
||||
@@ -272,6 +275,9 @@
|
||||
|
||||
@foreach ($accessories as $accessory)
|
||||
@if ($accessory)
|
||||
@php
|
||||
if ($accessory->category->getEula()) $eulas[] = $accessory->category->getEula()
|
||||
@endphp
|
||||
<tr>
|
||||
<td>{{ $acounter }}</td>
|
||||
<td>
|
||||
@@ -332,10 +338,11 @@
|
||||
|
||||
@foreach ($consumables as $consumable)
|
||||
@if ($consumable)
|
||||
@php
|
||||
if ($consumable->category->getEula()) $eulas[] = $consumable->category->getEula()
|
||||
@endphp
|
||||
<tr>
|
||||
<td>{{ $ccounter }}</td>
|
||||
|
||||
|
||||
<td>
|
||||
@if ($consumable->deleted_at!='')
|
||||
<td>{{ ($consumable->manufacturer) ? $consumable->manufacturer->name : '' }} {{ $consumable->name }} {{ $consumable->model_number }}</td>
|
||||
@@ -359,12 +366,32 @@
|
||||
</table>
|
||||
@endif
|
||||
|
||||
<p></p>
|
||||
<div class="pull-right">
|
||||
<button class="btn btn-default hidden-print" type="button" data-toggle="collapse" data-target="#eula-row" aria-expanded="false" aria-controls="eula-row" title="EULAs">
|
||||
<i class="fa fa-eye-slash"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<table style="margin-top: 80px;">
|
||||
<tr class="collapse" id="eula-row">
|
||||
<td style="padding-right: 10px; vertical-align: top; font-weight: bold;">EULA</td>
|
||||
<td style="padding-right: 10px; vertical-align: top; padding-bottom: 80px;" colspan="3">
|
||||
@php
|
||||
if (!empty($eulas)) $eulas = array_unique($eulas);
|
||||
@endphp
|
||||
@if (!empty($eulas))
|
||||
@foreach ($eulas as $key => $eula)
|
||||
{!! $eula !!}
|
||||
@endforeach
|
||||
@endif
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding-right: 10px; vertical-align: top; font-weight: bold;">{{ trans('general.signed_off_by') }}:</td>
|
||||
<td style="padding-right: 10px; vertical-align: top;">________________________________________________________</td>
|
||||
<td style="padding-right: 10px; vertical-align: top;">________________________________________________________</td>
|
||||
<td>_____________________</td>
|
||||
<td style="padding-right: 10px; vertical-align: top;">______________________________________</td>
|
||||
<td style="padding-right: 10px; vertical-align: top;">______________________________________</td>
|
||||
<td>_____________</td>
|
||||
</tr>
|
||||
<tr style="height: 80px;">
|
||||
<td></td>
|
||||
@@ -372,12 +399,11 @@
|
||||
<td style="padding-right: 10px; vertical-align: top;">Signature</td>
|
||||
<td style="padding-right: 10px; vertical-align: top;">{{ trans('general.date') }}</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td style="padding-right: 10px; vertical-align: top; font-weight: bold;">{{ trans('admin/users/table.manager') }}:</td>
|
||||
<td style="padding-right: 10px; vertical-align: top;">________________________________________________________</td>
|
||||
<td style="padding-right: 10px; vertical-align: top;">________________________________________________________</td>
|
||||
<td>_____________________</td>
|
||||
<td style="padding-right: 10px; vertical-align: top;">______________________________________</td>
|
||||
<td style="padding-right: 10px; vertical-align: top;">______________________________________</td>
|
||||
<td>_____________</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
@@ -392,11 +418,6 @@
|
||||
{{-- Javascript files --}}
|
||||
<script src="{{ url(mix('js/dist/all.js')) }}" nonce="{{ csrf_token() }}"></script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<script src="{{ url(mix('js/dist/bootstrap-table.js')) }}"></script>
|
||||
|
||||
<script>
|
||||
@@ -475,7 +496,5 @@
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -549,28 +549,28 @@ Route::group(['prefix' => 'v1', 'middleware' => ['api', 'throttle:api']], functi
|
||||
Api\AssetFilesController::class,
|
||||
'store'
|
||||
]
|
||||
)->name('api.assets.files');
|
||||
)->name('api.assets.files.store');
|
||||
|
||||
Route::get('{asset_id}/files',
|
||||
[
|
||||
Api\AssetFilesController::class,
|
||||
'list'
|
||||
]
|
||||
)->name('api.assets.files');
|
||||
)->name('api.assets.files.index');
|
||||
|
||||
Route::get('{asset_id}/file/{file_id}',
|
||||
[
|
||||
Api\AssetFilesController::class,
|
||||
'show'
|
||||
]
|
||||
)->name('api.assets.file');
|
||||
)->name('api.assets.files.show');
|
||||
|
||||
Route::delete('{asset_id}/file/{file_id}',
|
||||
[
|
||||
Api\AssetFilesController::class,
|
||||
'destroy'
|
||||
]
|
||||
)->name('api.assets.file');
|
||||
)->name('api.assets.files.destroy');
|
||||
|
||||
});
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ class AssetFilesTest extends TestCase
|
||||
//Upload a file
|
||||
$this->actingAsForApi($user)
|
||||
->post(
|
||||
route('api.assets.files', ['asset_id' => $asset[0]["id"]]), [
|
||||
route('api.assets.files.store', ['asset_id' => $asset[0]["id"]]), [
|
||||
'file' => [UploadedFile::fake()->create("test.jpg", 100)]
|
||||
])
|
||||
->assertOk();
|
||||
@@ -41,7 +41,7 @@ class AssetFilesTest extends TestCase
|
||||
// List the files
|
||||
$this->actingAsForApi($user)
|
||||
->getJson(
|
||||
route('api.assets.files', ['asset_id' => $asset[0]["id"]]))
|
||||
route('api.assets.files.index', ['asset_id' => $asset[0]["id"]]))
|
||||
->assertOk()
|
||||
->assertJsonStructure([
|
||||
'status',
|
||||
@@ -63,7 +63,7 @@ class AssetFilesTest extends TestCase
|
||||
//Upload a file
|
||||
$this->actingAsForApi($user)
|
||||
->post(
|
||||
route('api.assets.files', ['asset_id' => $asset[0]["id"]]), [
|
||||
route('api.assets.files.store', ['asset_id' => $asset[0]["id"]]), [
|
||||
'file' => [UploadedFile::fake()->create("test.jpg", 100)]
|
||||
])
|
||||
->assertOk();
|
||||
@@ -71,13 +71,13 @@ class AssetFilesTest extends TestCase
|
||||
// List the files to get the file ID
|
||||
$result = $this->actingAsForApi($user)
|
||||
->getJson(
|
||||
route('api.assets.files', ['asset_id' => $asset[0]["id"]]))
|
||||
route('api.assets.files.index', ['asset_id' => $asset[0]["id"]]))
|
||||
->assertOk();
|
||||
|
||||
// Get the file
|
||||
$this->actingAsForApi($user)
|
||||
->get(
|
||||
route('api.assets.file', [
|
||||
route('api.assets.files.show', [
|
||||
'asset_id' => $asset[0]["id"],
|
||||
'file_id' => $result->decodeResponseJson()->json()["payload"][0]["id"],
|
||||
]))
|
||||
@@ -97,7 +97,7 @@ class AssetFilesTest extends TestCase
|
||||
//Upload a file
|
||||
$this->actingAsForApi($user)
|
||||
->post(
|
||||
route('api.assets.files', ['asset_id' => $asset[0]["id"]]), [
|
||||
route('api.assets.files.store', ['asset_id' => $asset[0]["id"]]), [
|
||||
'file' => [UploadedFile::fake()->create("test.jpg", 100)]
|
||||
])
|
||||
->assertOk();
|
||||
@@ -105,13 +105,13 @@ class AssetFilesTest extends TestCase
|
||||
// List the files to get the file ID
|
||||
$result = $this->actingAsForApi($user)
|
||||
->getJson(
|
||||
route('api.assets.files', ['asset_id' => $asset[0]["id"]]))
|
||||
route('api.assets.files.index', ['asset_id' => $asset[0]["id"]]))
|
||||
->assertOk();
|
||||
|
||||
// Delete the file
|
||||
$this->actingAsForApi($user)
|
||||
->delete(
|
||||
route('api.assets.file', [
|
||||
route('api.assets.files.destroy', [
|
||||
'asset_id' => $asset[0]["id"],
|
||||
'file_id' => $result->decodeResponseJson()->json()["payload"][0]["id"],
|
||||
]))
|
||||
|
||||
18
tests/Feature/Console/OptimizeTest.php
Normal file
18
tests/Feature/Console/OptimizeTest.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature\Console;
|
||||
|
||||
use Tests\TestCase;
|
||||
|
||||
class OptimizeTest extends TestCase
|
||||
{
|
||||
public function testOptimizeSucceeds()
|
||||
{
|
||||
$this->beforeApplicationDestroyed(function () {
|
||||
$this->artisan('config:clear');
|
||||
$this->artisan('route:clear');
|
||||
});
|
||||
|
||||
$this->artisan('optimize')->assertSuccessful();
|
||||
}
|
||||
}
|
||||
61
tests/Feature/Reporting/UnacceptedAssetReportTest.php
Normal file
61
tests/Feature/Reporting/UnacceptedAssetReportTest.php
Normal file
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature\Reporting;
|
||||
|
||||
use App\Models\Asset;
|
||||
use App\Models\Company;
|
||||
use App\Models\User;
|
||||
use Illuminate\Testing\TestResponse;
|
||||
use League\Csv\Reader;
|
||||
use PHPUnit\Framework\Assert;
|
||||
use Tests\TestCase;
|
||||
|
||||
class UnacceptedAssetReportTest extends TestCase
|
||||
{
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
TestResponse::macro(
|
||||
'assertSeeTextInStreamedResponse',
|
||||
function (string $needle) {
|
||||
Assert::assertTrue(
|
||||
collect(Reader::createFromString($this->streamedContent())->getRecords())
|
||||
->pluck(0)
|
||||
->contains($needle)
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
);
|
||||
|
||||
TestResponse::macro(
|
||||
'assertDontSeeTextInStreamedResponse',
|
||||
function (string $needle) {
|
||||
Assert::assertFalse(
|
||||
collect(Reader::createFromString($this->streamedContent())->getRecords())
|
||||
->pluck(0)
|
||||
->contains($needle)
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
public function testPermissionRequiredToViewUnacceptedAssetReport()
|
||||
{
|
||||
$this->actingAs(User::factory()->create())
|
||||
->get(route('reports/unaccepted_assets'))
|
||||
->assertForbidden();
|
||||
}
|
||||
|
||||
public function testUserCanListUnacceptedAssets()
|
||||
{
|
||||
$this->actingAs(User::factory()->superuser()->create())
|
||||
->get(route('reports/unaccepted_assets'))
|
||||
->assertOk();
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user