Compare commits

...

38 Commits

Author SHA1 Message Date
snipe
276950072f This may be more work than we want to do here tbh
Signed-off-by: snipe <snipe@snipe.net>
2024-07-18 14:14:40 +01:00
snipe
52344c5574 Better
Signed-off-by: snipe <snipe@snipe.net>
2024-07-18 13:02:22 +01:00
snipe
8cfca8bff7 Ack
Signed-off-by: snipe <snipe@snipe.net>
2024-07-18 12:56:28 +01:00
snipe
f400b38c9c First stab
Signed-off-by: snipe <snipe@snipe.net>
2024-07-18 11:53:30 +01:00
snipe
ee589ca112 Merge pull request #15088 from mauro-miatello/develop
Added EULAs in print user's assets
2024-07-18 09:09:34 +01:00
snipe
1eb16cdb02 Merge pull request #15111 from marcusmoore/fixes/optimize-test
Undo `optimize` command in test after it is completed
2024-07-17 21:03:01 +01:00
Marcus Moore
a56f3f85f8 Clear the config and route caching done by optimize command after test 2024-07-17 12:21:46 -07:00
snipe
239824681d Merge pull request #15075 from akemidx/checkintranslation
FIXED: Missing Translation on a Tooltip
2024-07-17 18:16:02 +01:00
snipe
0ac82fbbe1 Merge pull request #15084 from snipe/fixes_ldap_sync_locale
Fixes #15067 - updated ldap sync locale to use `app()->getLocale()`
2024-07-17 18:15:32 +01:00
snipe
8c5a9fa38f Merge pull request #15089 from snipe/dependabot/github_actions/develop/codacy/codacy-analysis-cli-action-4.4.5
Bump codacy/codacy-analysis-cli-action from 4.4.1 to 4.4.5
2024-07-17 16:47:28 +01:00
snipe
65dcb2a9bd Merge pull request #15085 from snipe/small_tweaks_to_oauth_page
Small layout tweaks to oauth page
2024-07-16 21:36:17 +01:00
snipe
a0d461d3e2 Merge pull request #15099 from snipe/fixes/15094_wrong_translation_string
Fixed #15094 - wrong translation string for model on checkout
2024-07-16 17:23:46 +01:00
snipe
eb9e276ba7 Fixed #15094 - wrong translation string for model on checkout
Signed-off-by: snipe <snipe@snipe.net>
2024-07-16 17:14:13 +01:00
snipe
35160f88e0 Corrected return type
Signed-off-by: snipe <snipe@snipe.net>
2024-07-16 16:09:08 +01:00
dependabot[bot]
0ddb447c4c Bump codacy/codacy-analysis-cli-action from 4.4.1 to 4.4.5
Bumps [codacy/codacy-analysis-cli-action](https://github.com/codacy/codacy-analysis-cli-action) from 4.4.1 to 4.4.5.
- [Release notes](https://github.com/codacy/codacy-analysis-cli-action/releases)
- [Commits](https://github.com/codacy/codacy-analysis-cli-action/compare/v4.4.1...v4.4.5)

---
updated-dependencies:
- dependency-name: codacy/codacy-analysis-cli-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-07-15 08:39:24 +00:00
MrM
e49c96a35e Added EULAs in print user's assets
Added EULAs when we want to print all assets assigned to a users and ask him/her to sign.
2024-07-14 19:10:33 +02:00
snipe
2d1aeca949 Re-use existing string
Signed-off-by: snipe <snipe@snipe.net>
2024-07-13 18:24:56 +01:00
snipe
e06e4db4b7 Small layout tweaks to oauth page
Signed-off-by: snipe <snipe@snipe.net>
2024-07-13 18:16:03 +01:00
snipe
51242fcbb2 Merge branch 'develop' of https://github.com/snipe/snipe-it into develop 2024-07-13 16:09:03 +01:00
snipe
99be9ddb47 Add @dbakan as a contributor 2024-07-13 16:08:56 +01:00
snipe
be4317361d Merge pull request #15082 from dbakan/fix/optimize-command
Fixed #10224: fix route names for optimize command
2024-07-13 16:08:32 +01:00
Daniel Albertsen
a175b6a38b fix routes and tests 2024-07-13 16:36:14 +02:00
Daniel Albertsen
431da6c903 add test to ensure artisan optimize works 2024-07-13 16:36:14 +02:00
snipe
ab6b8f520e Fixed field name
Signed-off-by: snipe <snipe@snipe.net>
2024-07-13 15:25:37 +01:00
snipe
24e58d1455 Do not update users who already exist since that locale may have been overirrden manually
Signed-off-by: snipe <snipe@snipe.net>
2024-07-13 15:20:04 +01:00
snipe
f91ad6b2db Use app()->getLocale() to determine imported user’s language
Signed-off-by: snipe <snipe@snipe.net>
2024-07-13 15:15:44 +01:00
snipe
eed253bd2f Use app helped instead of facade
Signed-off-by: snipe <snipe@snipe.net>
2024-07-13 15:15:18 +01:00
snipe
b68fcf1de5 Added unaccepted asset test
Signed-off-by: snipe <snipe@snipe.net>
2024-07-12 12:19:40 +01:00
snipe
d21ebc6f0d Fixed return type
Signed-off-by: snipe <snipe@snipe.net>
2024-07-12 11:04:56 +01:00
akemidx
ad818cf886 missing translation 2024-07-11 17:13:47 -04:00
snipe
fb7d533ff7 Merge pull request #15073 from marcusmoore/feature/livewire-url-prefix
Allow setting a prefix for Livewire's update and asset urls
2024-07-11 21:04:50 +01:00
Marcus Moore
9dd3827222 Allow setting a prefix for Livewire's update and asset urls 2024-07-11 12:43:29 -07:00
snipe
5697370dfe Merge pull request #14722 from Godmartinz/unaccepted_reminder_command
Adds a command to resend acceptance emails
2024-07-11 20:37:04 +01:00
Godfrey M
442903ea5e trying to get link to work, fixed up markup and url 2024-05-23 16:08:18 -07:00
Godfrey M
d3ab152d30 adds reminder notification constructor and updates markdown 2024-05-23 12:47:02 -07:00
Godfrey M
8a0afae90f fixed query, fixed no email logic, needs new markdown 2024-05-21 09:42:00 -07:00
Godfrey M
c658a0fcb4 fixes description 2024-05-15 13:20:05 -07:00
Godfrey M
f40284c413 adds acceptance reminder command 2024-05-15 13:04:58 -07:00
33 changed files with 782 additions and 84 deletions

View File

@@ -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"
]
}
]
}

View File

@@ -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

View File

@@ -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

View File

@@ -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!

View File

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

View 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.');
}
}

View File

@@ -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);
}

View File

@@ -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;
}
/**

View File

@@ -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');

View File

@@ -45,7 +45,7 @@ class CheckLocale
}
\App::setLocale(Helper::mapLegacyLocale($language));
app()->setLocale(Helper::mapLegacyLocale($language));
return $next($request);
}
}

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

View File

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

View File

@@ -2,6 +2,8 @@
namespace App\Http\Transformers;
use Illuminate\Pagination\LengthAwarePaginator;
class DatatablesTransformer
{
public function transformDatatables($objects, $total = null)

View File

@@ -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;

View File

@@ -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') {

View 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();
}
}

View 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 [
//
];
}
}

View 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);
});
}
}

View File

@@ -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.

View File

@@ -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
View File

@@ -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",

View File

@@ -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,

View File

@@ -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),
];

View File

@@ -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',

View File

@@ -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">

View File

@@ -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

View File

@@ -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

View File

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

View File

@@ -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>

View File

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

View File

@@ -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"],
]))

View 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();
}
}

View 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();
}
}