Merge remote-tracking branch 'origin/develop'
Signed-off-by: snipe <snipe@snipe.net> # Conflicts: # public/css/dist/all.css # public/css/dist/bootstrap-table.css # public/js/dist/bootstrap-table.js # public/mix-manifest.json
This commit is contained in:
commit
5eb9f353b5
27 changed files with 372 additions and 79 deletions
|
@ -3307,6 +3307,15 @@
|
|||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "ntaylor-86",
|
||||
"name": "Nathan Taylor",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/28693782?v=4",
|
||||
"profile": "https://github.com/ntaylor-86",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ DB_USERNAME=snipeit
|
|||
DB_PASSWORD=changeme1234
|
||||
DB_PREFIX=null
|
||||
DB_DUMP_PATH='/usr/bin'
|
||||
DB_DUMP_SKIP_SSL=true
|
||||
DB_CHARSET=utf8mb4
|
||||
DB_COLLATION=utf8mb4_unicode_ci
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@ DB_PASSWORD=changeme1234
|
|||
MYSQL_ROOT_PASSWORD=changeme1234
|
||||
DB_PREFIX=null
|
||||
DB_DUMP_PATH='/usr/bin'
|
||||
DB_DUMP_SKIP_SSL=true
|
||||
DB_CHARSET=utf8mb4
|
||||
DB_COLLATION=utf8mb4_unicode_ci
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@ DB_USERNAME=null
|
|||
DB_PASSWORD=null
|
||||
DB_PREFIX=null
|
||||
DB_DUMP_PATH='/usr/bin'
|
||||
DB_DUMP_SKIP_SSL=false
|
||||
DB_CHARSET=utf8mb4
|
||||
DB_COLLATION=utf8mb4_unicode_ci
|
||||
DB_SANITIZE_BY_DEFAULT=false
|
||||
|
|
|
@ -54,6 +54,7 @@ Thanks goes to all of these wonderful people ([emoji key](https://github.com/ken
|
|||
| [<img src="https://avatars.githubusercontent.com/u/64061710?v=4" width="110px;"/><br /><sub>U-H-T</sub>](https://github.com/U-H-T)<br />[💻](https://github.com/snipe/snipe-it/commits?author=U-H-T "Code") | [<img src="https://avatars.githubusercontent.com/u/5395363?v=4" width="110px;"/><br /><sub>Matt Tyree</sub>](https://github.com/Tyree)<br />[📖](https://github.com/snipe/snipe-it/commits?author=Tyree "Documentation") | [<img src="https://avatars.githubusercontent.com/u/292081?v=4" width="110px;"/><br /><sub>Florent Bervas</sub>](http://spoontux.net)<br />[💻](https://github.com/snipe/snipe-it/commits?author=FlorentDotMe "Code") | [<img src="https://avatars.githubusercontent.com/u/4498077?v=4" width="110px;"/><br /><sub>Daniel Albertsen</sub>](https://ditscheri.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=dbakan "Code") | [<img src="https://avatars.githubusercontent.com/u/100710244?v=4" width="110px;"/><br /><sub>r-xyz</sub>](https://github.com/r-xyz)<br />[💻](https://github.com/snipe/snipe-it/commits?author=r-xyz "Code") | [<img src="https://avatars.githubusercontent.com/u/47491036?v=4" width="110px;"/><br /><sub>Steven Mainor</sub>](https://github.com/DrekiDegga)<br />[💻](https://github.com/snipe/snipe-it/commits?author=DrekiDegga "Code") | [<img src="https://avatars.githubusercontent.com/u/65785975?v=4" width="110px;"/><br /><sub>arne-kroeger</sub>](https://github.com/arne-kroeger)<br />[💻](https://github.com/snipe/snipe-it/commits?author=arne-kroeger "Code") |
|
||||
| [<img src="https://avatars.githubusercontent.com/u/167117705?v=4" width="110px;"/><br /><sub>Glukose1</sub>](https://github.com/Glukose1)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Glukose1 "Code") | [<img src="https://avatars.githubusercontent.com/u/1197791?v=4" width="110px;"/><br /><sub>Scarzy</sub>](https://github.com/Scarzy)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Scarzy "Code") | [<img src="https://avatars.githubusercontent.com/u/37372069?v=4" width="110px;"/><br /><sub>setpill</sub>](https://github.com/setpill)<br />[💻](https://github.com/snipe/snipe-it/commits?author=setpill "Code") | [<img src="https://avatars.githubusercontent.com/u/3755203?v=4" width="110px;"/><br /><sub>swift2512</sub>](https://github.com/swift2512)<br />[🐛](https://github.com/snipe/snipe-it/issues?q=author%3Aswift2512 "Bug reports") | [<img src="https://avatars.githubusercontent.com/u/6136439?v=4" width="110px;"/><br /><sub>Darren Rainey</sub>](https://darrenraineys.co.uk)<br />[💻](https://github.com/snipe/snipe-it/commits?author=DarrenRainey "Code") | [<img src="https://avatars.githubusercontent.com/u/133033121?v=4" width="110px;"/><br /><sub>maciej-poleszczyk</sub>](https://github.com/maciej-poleszczyk)<br />[💻](https://github.com/snipe/snipe-it/commits?author=maciej-poleszczyk "Code") | [<img src="https://avatars.githubusercontent.com/u/143394709?v=4" width="110px;"/><br /><sub>Sebastian Groß</sub>](https://github.com/sgross-emlix)<br />[💻](https://github.com/snipe/snipe-it/commits?author=sgross-emlix "Code") |
|
||||
| [<img src="https://avatars.githubusercontent.com/u/41107778?v=4" width="110px;"/><br /><sub>Anouar Touati</sub>](https://github.com/AnouarTouati)<br />[💻](https://github.com/snipe/snipe-it/commits?author=AnouarTouati "Code") | [<img src="https://avatars.githubusercontent.com/u/25596663?v=4" width="110px;"/><br /><sub>aHVzY2g</sub>](https://github.com/aHVzY2g)<br />[💻](https://github.com/snipe/snipe-it/commits?author=aHVzY2g "Code") | [<img src="https://avatars.githubusercontent.com/u/13408130?v=4" width="110px;"/><br /><sub>林博仁 Buo-ren Lin</sub>](https://brlin.me)<br />[💻](https://github.com/snipe/snipe-it/commits?author=brlin-tw "Code") | [<img src="https://avatars.githubusercontent.com/u/18550946?v=4" width="110px;"/><br /><sub>Adugna Gizaw</sub>](https://orbalia.pythonanywhere.com/)<br />[🌍](#translation-addex12 "Translation") | [<img src="https://avatars.githubusercontent.com/u/760989?v=4" width="110px;"/><br /><sub>Jesse Ostrander</sub>](https://github.com/jostrander)<br />[💻](https://github.com/snipe/snipe-it/commits?author=jostrander "Code") | [<img src="https://avatars.githubusercontent.com/u/31522486?v=4" width="110px;"/><br /><sub>James M</sub>](https://github.com/azmcnutt)<br />[💻](https://github.com/snipe/snipe-it/commits?author=azmcnutt "Code") | [<img src="https://avatars.githubusercontent.com/u/5183146?v=4" width="110px;"/><br /><sub>Fiala06</sub>](https://github.com/Fiala06)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Fiala06 "Code") |
|
||||
| [<img src="https://avatars.githubusercontent.com/u/28693782?v=4" width="110px;"/><br /><sub>Nathan Taylor</sub>](https://github.com/ntaylor-86)<br />[💻](https://github.com/snipe/snipe-it/commits?author=ntaylor-86 "Code") |
|
||||
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
||||
|
||||
This project follows the [all-contributors](https://github.com/kentcdodds/all-contributors) specification. Contributions of any kind welcome!
|
||||
|
|
|
@ -570,7 +570,6 @@ class BulkAssetsController extends Controller
|
|||
*/
|
||||
public function storeCheckout(AssetCheckoutRequest $request) : RedirectResponse | ModelNotFoundException
|
||||
{
|
||||
|
||||
$this->authorize('checkout', Asset::class);
|
||||
|
||||
try {
|
||||
|
@ -584,6 +583,8 @@ class BulkAssetsController extends Controller
|
|||
|
||||
$asset_ids = array_filter($request->get('selected_assets'));
|
||||
|
||||
$assets = Asset::findOrFail($asset_ids);
|
||||
|
||||
if (request('checkout_to_type') == 'asset') {
|
||||
foreach ($asset_ids as $asset_id) {
|
||||
if ($target->id == $asset_id) {
|
||||
|
@ -603,9 +604,8 @@ class BulkAssetsController extends Controller
|
|||
}
|
||||
|
||||
$errors = [];
|
||||
DB::transaction(function () use ($target, $admin, $checkout_at, $expected_checkin, &$errors, $asset_ids, $request) { //NOTE: $errors is passsed by reference!
|
||||
foreach ($asset_ids as $asset_id) {
|
||||
$asset = Asset::findOrFail($asset_id);
|
||||
DB::transaction(function () use ($target, $admin, $checkout_at, $expected_checkin, &$errors, $assets, $request) { //NOTE: $errors is passsed by reference!
|
||||
foreach ($assets as $asset) {
|
||||
$this->authorize('checkout', $asset);
|
||||
|
||||
$checkout_success = $asset->checkOut($target, $admin, $checkout_at, $expected_checkin, e($request->get('note')), $asset->name, null);
|
||||
|
@ -632,7 +632,7 @@ class BulkAssetsController extends Controller
|
|||
// Redirect to the asset management page with error
|
||||
return redirect()->route('hardware.bulkcheckout.show')->withInput()->with('error', trans_choice('admin/hardware/message.multi-checkout.error', $asset_ids))->withErrors($errors);
|
||||
} catch (ModelNotFoundException $e) {
|
||||
return redirect()->route('hardware.bulkcheckout.show')->with('error', $e->getErrors());
|
||||
return redirect()->route('hardware.bulkcheckout.show')->withInput()->with('error', trans_choice('admin/hardware/message.multi-checkout.error', $request->input('selected_assets')));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -493,6 +493,17 @@ class ReportsController extends Controller
|
|||
$header[] = trans('admin/hardware/table.eol');
|
||||
}
|
||||
|
||||
if ($request->filled('warranty')) {
|
||||
$header[] = trans('admin/hardware/form.warranty');
|
||||
$header[] = trans('admin/hardware/form.warranty_expires');
|
||||
}
|
||||
|
||||
if ($request->filled('depreciation')) {
|
||||
$header[] = trans('admin/hardware/table.book_value');
|
||||
$header[] = trans('admin/hardware/table.diff');
|
||||
$header[] = trans('admin/hardware/form.fully_depreciated');
|
||||
}
|
||||
|
||||
if ($request->filled('order')) {
|
||||
$header[] = trans('admin/hardware/form.order');
|
||||
}
|
||||
|
@ -579,17 +590,6 @@ class ReportsController extends Controller
|
|||
$header[] = trans('general.status');
|
||||
}
|
||||
|
||||
if ($request->filled('warranty')) {
|
||||
$header[] = trans('admin/hardware/form.warranty');
|
||||
$header[] = trans('admin/hardware/form.warranty_expires');
|
||||
}
|
||||
|
||||
if ($request->filled('depreciation')) {
|
||||
$header[] = trans('admin/hardware/table.book_value');
|
||||
$header[] = trans('admin/hardware/table.diff');
|
||||
$header[] = trans('admin/hardware/form.fully_depreciated');
|
||||
}
|
||||
|
||||
if ($request->filled('checkout_date')) {
|
||||
$header[] = trans('admin/hardware/table.checkout_date');
|
||||
}
|
||||
|
@ -805,6 +805,19 @@ class ReportsController extends Controller
|
|||
$row[] = ($asset->purchase_date != '') ? $asset->asset_eol_date : '';
|
||||
}
|
||||
|
||||
if ($request->filled('warranty')) {
|
||||
$row[] = ($asset->warranty_months) ? $asset->warranty_months : '';
|
||||
$row[] = $asset->present()->warranty_expires();
|
||||
}
|
||||
|
||||
if ($request->filled('depreciation')) {
|
||||
$depreciation = $asset->getDepreciatedValue();
|
||||
$diff = ($asset->purchase_cost - $depreciation);
|
||||
$row[] = Helper::formatCurrencyOutput($depreciation);
|
||||
$row[] = Helper::formatCurrencyOutput($diff);
|
||||
$row[] = (($asset->depreciation) && ($asset->depreciated_date())) ? $asset->depreciated_date()->format('Y-m-d') : '';
|
||||
}
|
||||
|
||||
if ($request->filled('order')) {
|
||||
$row[] = ($asset->order_number) ? $asset->order_number : '';
|
||||
}
|
||||
|
@ -938,19 +951,6 @@ class ReportsController extends Controller
|
|||
$row[] = ($asset->assetstatus) ? $asset->assetstatus->name.' ('.$asset->present()->statusMeta.')' : '';
|
||||
}
|
||||
|
||||
if ($request->filled('warranty')) {
|
||||
$row[] = ($asset->warranty_months) ? $asset->warranty_months : '';
|
||||
$row[] = $asset->present()->warranty_expires();
|
||||
}
|
||||
|
||||
if ($request->filled('depreciation')) {
|
||||
$depreciation = $asset->getDepreciatedValue();
|
||||
$diff = ($asset->purchase_cost - $depreciation);
|
||||
$row[] = Helper::formatCurrencyOutput($depreciation);
|
||||
$row[] = Helper::formatCurrencyOutput($diff);
|
||||
$row[] = (($asset->depreciation) && ($asset->depreciated_date())) ? $asset->depreciated_date()->format('Y-m-d') : '';
|
||||
}
|
||||
|
||||
if ($request->filled('checkout_date')) {
|
||||
$row[] = ($asset->last_checkout) ? $asset->last_checkout : '';
|
||||
}
|
||||
|
|
|
@ -395,13 +395,22 @@ class UsersController extends Controller
|
|||
// Make sure the user can view users at all
|
||||
$this->authorize('view', User::class);
|
||||
|
||||
$user = User::with('assets', 'assets.model', 'consumables', 'accessories', 'licenses', 'userloc')->withTrashed()->find($user->id);
|
||||
$user = User::with([
|
||||
'consumables',
|
||||
'accessories',
|
||||
'licenses',
|
||||
'userloc',
|
||||
])
|
||||
->withTrashed()
|
||||
->find($user->id);
|
||||
|
||||
// Make sure they can view this particular user
|
||||
$this->authorize('view', $user);
|
||||
|
||||
$userlog = $user->userlog->load('item');
|
||||
return view('users/view', compact('user', 'userlog'))->with('settings', Setting::getSettings());
|
||||
return view('users/view', [
|
||||
'user' => $user,
|
||||
'settings' => Setting::getSettings(),
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -29,6 +29,12 @@ class StoreLabelSettings extends FormRequest
|
|||
return $label->getName();
|
||||
})->values()->toArray();
|
||||
|
||||
if (empty($this->input('label2_template'))) {
|
||||
$this->merge([
|
||||
'label2_template' => 'DefaultLabel',
|
||||
]);
|
||||
}
|
||||
|
||||
return [
|
||||
'labels_per_page' => 'numeric',
|
||||
'labels_width' => 'numeric',
|
||||
|
|
|
@ -101,11 +101,8 @@ class LocationsTransformer
|
|||
$array = [
|
||||
'id' => $accessory_checkout->id,
|
||||
'assigned_to' => $accessory_checkout->assigned_to,
|
||||
'accessory' => [
|
||||
'id' => $accessory_checkout->accessory->id,
|
||||
'name' => $accessory_checkout->accessory->name,
|
||||
],
|
||||
'image' => ($accessory_checkout->accessory->image) ? Storage::disk('public')->url('accessories/'.e($accessory_checkout->accessory->image)) : null,
|
||||
'accessory' => $this->transformAccessory($accessory_checkout->accessory),
|
||||
'image' => ($accessory_checkout?->accessory?->image) ? Storage::disk('public')->url('accessories/' . e($accessory_checkout->accessory->image)) : null,
|
||||
'note' => $accessory_checkout->note ? e($accessory_checkout->note) : null,
|
||||
'created_by' => $accessory_checkout->adminuser ? [
|
||||
'id' => (int) $accessory_checkout->adminuser->id,
|
||||
|
@ -153,4 +150,16 @@ class LocationsTransformer
|
|||
return $array;
|
||||
}
|
||||
}
|
||||
|
||||
private function transformAccessory(?Accessory $accessory): ?array
|
||||
{
|
||||
if ($accessory) {
|
||||
return [
|
||||
'id' => $accessory->id,
|
||||
'name' => $accessory->name,
|
||||
];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -67,7 +67,8 @@ final class Company extends SnipeModel
|
|||
'phone',
|
||||
'fax',
|
||||
'email',
|
||||
'created_by'
|
||||
'created_by',
|
||||
'notes',
|
||||
];
|
||||
|
||||
private static function isFullMultipleCompanySupportEnabled()
|
||||
|
|
|
@ -81,6 +81,7 @@ return [
|
|||
'unix_socket' => env('DB_SOCKET', ''),
|
||||
'dump' => [
|
||||
'dump_binary_path' => env('DB_DUMP_PATH', '/usr/local/bin'), // only the path, so without 'mysqldump'
|
||||
'skip_ssl' => env('DB_DUMP_SKIP_SSL', false), // turn off SSL if not available
|
||||
'use_single_transaction' => false,
|
||||
'timeout' => 60 * 5, // 5 minute timeout
|
||||
//'exclude_tables' => ['table1', 'table2'],
|
||||
|
|
|
@ -295,6 +295,11 @@ class UserFactory extends Factory
|
|||
return $this->appendPermission(['companies.delete' => '1']);
|
||||
}
|
||||
|
||||
public function editCompanies()
|
||||
{
|
||||
return $this->appendPermission(['companies.edit' => '1']);
|
||||
}
|
||||
|
||||
public function viewUsers()
|
||||
{
|
||||
return $this->appendPermission(['users.view' => '1']);
|
||||
|
|
16
package-lock.json
generated
16
package-lock.json
generated
|
@ -6,7 +6,7 @@
|
|||
"": {
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-free": "^6.7.2",
|
||||
"acorn": "^8.12.0",
|
||||
"acorn": "^8.14.1",
|
||||
"acorn-import-assertions": "^1.9.0",
|
||||
"admin-lte": "^2.4.18",
|
||||
"ajv": "^6.12.6",
|
||||
|
@ -15,7 +15,7 @@
|
|||
"bootstrap-colorpicker": "^2.5.3",
|
||||
"bootstrap-datepicker": "^1.10.0",
|
||||
"bootstrap-less": "^3.3.8",
|
||||
"bootstrap-table": "1.24.0",
|
||||
"bootstrap-table": "1.24.1",
|
||||
"canvas-confetti": "^1.9.3",
|
||||
"chart.js": "^2.9.4",
|
||||
"clipboard": "^2.0.11",
|
||||
|
@ -2502,9 +2502,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/acorn": {
|
||||
"version": "8.14.0",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz",
|
||||
"integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==",
|
||||
"version": "8.14.1",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz",
|
||||
"integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==",
|
||||
"bin": {
|
||||
"acorn": "bin/acorn"
|
||||
},
|
||||
|
@ -3702,9 +3702,9 @@
|
|||
"license": "MIT"
|
||||
},
|
||||
"node_modules/bootstrap-table": {
|
||||
"version": "1.24.0",
|
||||
"resolved": "https://registry.npmjs.org/bootstrap-table/-/bootstrap-table-1.24.0.tgz",
|
||||
"integrity": "sha512-dyRf5PQwTgFHj9yjuPXa+GIf4JpuQhsgD1CJrOqhw40qI2gTb3mJfRdoBc7iF2bqzOl+k0RnbAlhSPbGe4VS+w==",
|
||||
"version": "1.24.1",
|
||||
"resolved": "https://registry.npmjs.org/bootstrap-table/-/bootstrap-table-1.24.1.tgz",
|
||||
"integrity": "sha512-que7o2Z6R0I3cfwfm6qg4XnoUK9A/8162HUErFYg3fGtzjk5OjLJx6Ji9p3oKz+IAIVvBCr9sqMqujEG47k3zA==",
|
||||
"peerDependencies": {
|
||||
"jquery": "3"
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-free": "^6.7.2",
|
||||
"acorn": "^8.12.0",
|
||||
"acorn": "^8.14.1",
|
||||
"acorn-import-assertions": "^1.9.0",
|
||||
"admin-lte": "^2.4.18",
|
||||
"ajv": "^6.12.6",
|
||||
|
@ -35,7 +35,7 @@
|
|||
"bootstrap-colorpicker": "^2.5.3",
|
||||
"bootstrap-datepicker": "^1.10.0",
|
||||
"bootstrap-less": "^3.3.8",
|
||||
"bootstrap-table": "1.24.0",
|
||||
"bootstrap-table": "1.24.1",
|
||||
"canvas-confetti": "^1.9.3",
|
||||
"chart.js": "^2.9.4",
|
||||
"clipboard": "^2.0.11",
|
||||
|
|
2
public/js/dist/bootstrap-table-en-US.min.js
vendored
2
public/js/dist/bootstrap-table-en-US.min.js
vendored
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bootstrap-table - An extended table to integration with some of the most widely used CSS frameworks. (Supports Bootstrap, Semantic UI, Bulma, Material Design, Foundation)
|
||||
*
|
||||
* @version v1.24.0
|
||||
* @version v1.24.1
|
||||
* @homepage https://bootstrap-table.com
|
||||
* @author wenzhixin <wenzhixin2010@gmail.com> (http://wenzhixin.net.cn/)
|
||||
* @license MIT
|
||||
|
|
File diff suppressed because one or more lines are too long
2
public/js/dist/bootstrap-table.js
vendored
2
public/js/dist/bootstrap-table.js
vendored
File diff suppressed because one or more lines are too long
|
@ -19,7 +19,7 @@
|
|||
"/css/dist/skins/skin-blue.css": "/css/dist/skins/skin-blue.css?id=091d9625203be910caca3e229afe438f",
|
||||
"/css/dist/skins/skin-blue-dark.css": "/css/dist/skins/skin-blue-dark.css?id=18787b3f00a3be7be38ee4e26cbd2a07",
|
||||
"/css/dist/skins/skin-black.css": "/css/dist/skins/skin-black.css?id=1f33ca3d860461c1127ec465ab3ebb6b",
|
||||
"/css/dist/all.css": "/css/dist/all.css?id=8c095763cd1a12d882e050d89d314ef9",
|
||||
"/css/dist/all.css": "/css/dist/all.css?id=e06ce6503c567fecd77ad3fe64250fe2",
|
||||
"/css/dist/signature-pad.css": "/css/dist/signature-pad.css?id=6a89d3cd901305e66ced1cf5f13147f7",
|
||||
"/css/dist/signature-pad.min.css": "/css/dist/signature-pad.min.css?id=6a89d3cd901305e66ced1cf5f13147f7",
|
||||
"/js/select2/i18n/af.js": "/js/select2/i18n/af.js?id=4f6fcd73488ce79fae1b7a90aceaecde",
|
||||
|
@ -90,8 +90,8 @@
|
|||
"/css/webfonts/fa-solid-900.woff2": "/css/webfonts/fa-solid-900.woff2?id=109ad919b74a62a8a223361da1651bbc",
|
||||
"/css/webfonts/fa-v4compatibility.ttf": "/css/webfonts/fa-v4compatibility.ttf?id=53c2e50ef821f7b8dd514611d5e0772c",
|
||||
"/css/webfonts/fa-v4compatibility.woff2": "/css/webfonts/fa-v4compatibility.woff2?id=331c85bd61ffa93af09273d1bc2add5a",
|
||||
"/js/dist/bootstrap-table-locale-all.min.js": "/js/dist/bootstrap-table-locale-all.min.js?id=02dfc50d5b951dc6d260bd508968d319",
|
||||
"/js/dist/bootstrap-table-en-US.min.js": "/js/dist/bootstrap-table-en-US.min.js?id=1c350eabf064c309f67d6779e5cc4afa",
|
||||
"/js/dist/bootstrap-table-locale-all.min.js": "/js/dist/bootstrap-table-locale-all.min.js?id=5e93ef0a1889bed3f92a705dc1e92c9b",
|
||||
"/js/dist/bootstrap-table-en-US.min.js": "/js/dist/bootstrap-table-en-US.min.js?id=c0f21fb7e62d6f0a0153f1cdbf26782a",
|
||||
"/css/dist/skins/_all-skins.min.css": "/css/dist/skins/_all-skins.min.css?id=6bf62cdec2477f3176df196fd0c99662",
|
||||
"/css/dist/skins/skin-black-dark.min.css": "/css/dist/skins/skin-black-dark.min.css?id=d34ae2483cbe2c77478c45f4006eba55",
|
||||
"/css/dist/skins/skin-black.min.css": "/css/dist/skins/skin-black.min.css?id=1f33ca3d860461c1127ec465ab3ebb6b",
|
||||
|
@ -108,8 +108,8 @@
|
|||
"/css/dist/skins/skin-red.min.css": "/css/dist/skins/skin-red.min.css?id=b9a74ec0cd68f83e7480d5ae39919beb",
|
||||
"/css/dist/skins/skin-yellow-dark.min.css": "/css/dist/skins/skin-yellow-dark.min.css?id=53edc92eb2d272744bc7404ec259930e",
|
||||
"/css/dist/skins/skin-yellow.min.css": "/css/dist/skins/skin-yellow.min.css?id=fc7adb943668ac69fe4b646625a7571f",
|
||||
"/css/dist/bootstrap-table.css": "/css/dist/bootstrap-table.css?id=ceded08e0cc745a83c13647035b03406",
|
||||
"/css/dist/bootstrap-table.css": "/css/dist/bootstrap-table.css?id=54d676a6ea8677dd48f6c4b3041292cf",
|
||||
"/js/build/vendor.js": "/js/build/vendor.js?id=89dffa552c6e3abe3a2aac6c9c7b466b",
|
||||
"/js/dist/bootstrap-table.js": "/js/dist/bootstrap-table.js?id=61285c8ac5ea7b46002ea8c451c94e60",
|
||||
"/js/dist/bootstrap-table.js": "/js/dist/bootstrap-table.js?id=757648759dcd365f5708e95b985971ff",
|
||||
"/js/dist/all.js": "/js/dist/all.js?id=1a7bd87b50e85aa4f2c4fd6f5ed7722c"
|
||||
}
|
||||
|
|
|
@ -292,8 +292,10 @@
|
|||
</div>
|
||||
<div class="col-md-9">
|
||||
|
||||
<span class="js-copy">{{ $consumable->item_no }}</span>
|
||||
<i class="fa-regular fa-clipboard js-copy-link" data-clipboard-target=".js-copy" aria-hidden="true" data-tooltip="true" data-placement="top" title="{{ trans('general.copy_to_clipboard') }}">
|
||||
<span class="js-copy-item_no">{{ $consumable->item_no }}</span>
|
||||
<i class="fa-regular fa-clipboard js-copy-link" data-clipboard-target=".js-copy-item_no"
|
||||
aria-hidden="true" data-tooltip="true" data-placement="top"
|
||||
title="{{ trans('general.copy_to_clipboard') }}">
|
||||
<span class="sr-only">{{ trans('general.copy_to_clipboard') }}</span>
|
||||
</i>
|
||||
|
||||
|
@ -308,8 +310,10 @@
|
|||
</div>
|
||||
<div class="col-md-9">
|
||||
|
||||
<span class="js-copy">{{ $consumable->model_number }}</span>
|
||||
<i class="fa-regular fa-clipboard js-copy-link" data-clipboard-target=".js-copy" aria-hidden="true" data-tooltip="true" data-placement="top" title="{{ trans('general.copy_to_clipboard') }}">
|
||||
<span class="js-copy-model_no">{{ $consumable->model_number }}</span>
|
||||
<i class="fa-regular fa-clipboard js-copy-link" data-clipboard-target=".js-copy-model_no"
|
||||
aria-hidden="true" data-tooltip="true" data-placement="top"
|
||||
title="{{ trans('general.copy_to_clipboard') }}">
|
||||
<span class="sr-only">{{ trans('general.copy_to_clipboard') }}</span>
|
||||
</i>
|
||||
|
||||
|
|
|
@ -726,15 +726,21 @@
|
|||
@endphp
|
||||
@if ($fieldSize>0)
|
||||
<span id="text-{{ $field->id }}-to-hide">{{ str_repeat('*', $fieldSize) }}</span>
|
||||
<span class="js-copy-{{ $field->id }} hidden-print" id="text-{{ $field->id }}-to-show" style="font-size: 0px;">
|
||||
@if (($field->format=='URL') && ($asset->{$field->db_column_name()}!=''))
|
||||
<a href="{{ Helper::gracefulDecrypt($field, $asset->{$field->db_column_name()}) }}" target="_new">{{ Helper::gracefulDecrypt($field, $asset->{$field->db_column_name()}) }}</a>
|
||||
@if (($field->format=='URL') && ($asset->{$field->db_column_name()}!=''))
|
||||
<span class="js-copy-{{ $field->id }} hidden-print"
|
||||
id="text-{{ $field->id }}-to-show"
|
||||
style="font-size: 0px;"><a
|
||||
href="{{ Helper::gracefulDecrypt($field, $asset->{$field->db_column_name()}) }}"
|
||||
target="_new">{{ Helper::gracefulDecrypt($field, $asset->{$field->db_column_name()}) }}</a></span>
|
||||
@elseif (($field->format=='DATE') && ($asset->{$field->db_column_name()}!=''))
|
||||
{{ \App\Helpers\Helper::gracefulDecrypt($field, \App\Helpers\Helper::getFormattedDateObject($asset->{$field->db_column_name()}, 'date', false)) }}
|
||||
<span class="js-copy-{{ $field->id }} hidden-print"
|
||||
id="text-{{ $field->id }}-to-show"
|
||||
style="font-size: 0px;">{{ \App\Helpers\Helper::gracefulDecrypt($field, \App\Helpers\Helper::getFormattedDateObject($asset->{$field->db_column_name()}, 'date', false)) }}</span>
|
||||
@else
|
||||
{{ Helper::gracefulDecrypt($field, $asset->{$field->db_column_name()}) }}
|
||||
<span class="js-copy-{{ $field->id }} hidden-print"
|
||||
id="text-{{ $field->id }}-to-show"
|
||||
style="font-size: 0px;">{{ Helper::gracefulDecrypt($field, $asset->{$field->db_column_name()}) }}</span>
|
||||
@endif
|
||||
</span>
|
||||
<i class="fa-regular fa-clipboard js-copy-link hidden-print" data-clipboard-target=".js-copy-{{ $field->id }}" aria-hidden="true" data-tooltip="true" data-placement="top" title="{{ trans('general.copy_to_clipboard') }}">
|
||||
<span class="sr-only">{{ trans('general.copy_to_clipboard') }}</span>
|
||||
</i>
|
||||
|
|
|
@ -56,7 +56,7 @@
|
|||
{{ trans('general.date') }}
|
||||
</th>
|
||||
<th class="col-sm-2" data-searchable="true" data-sortable="true" data-field="created_by" data-formatter="usersLinkObjFormatter">
|
||||
{{ trans('general.admin') }}
|
||||
{{ trans('general.created_by') }}
|
||||
</th>
|
||||
<th class="col-sm-2" data-field="action_type">
|
||||
{{ trans('general.action') }}
|
||||
|
|
|
@ -147,6 +147,16 @@
|
|||
{{ trans('admin/hardware/form.eol_date') }}
|
||||
</label>
|
||||
|
||||
<label class="form-control">
|
||||
<input type="checkbox" name="warranty" value="1" @checked($template->checkmarkValue('warranty')) />
|
||||
{{ trans('admin/hardware/form.warranty') }}
|
||||
</label>
|
||||
|
||||
<label class="form-control">
|
||||
<input type="checkbox" name="depreciation" value="1" @checked($template->checkmarkValue('depreciation')) />
|
||||
{{ trans('general.depreciation') }}
|
||||
</label>
|
||||
|
||||
<label class="form-control">
|
||||
<input type="checkbox" name="order" value="1" @checked($template->checkmarkValue('order')) />
|
||||
{{ trans('admin/hardware/form.order') }}
|
||||
|
@ -182,16 +192,6 @@
|
|||
{{ trans('general.status') }}
|
||||
</label>
|
||||
|
||||
<label class="form-control">
|
||||
<input type="checkbox" name="warranty" value="1" @checked($template->checkmarkValue('warranty')) />
|
||||
{{ trans('admin/hardware/form.warranty') }}
|
||||
</label>
|
||||
|
||||
<label class="form-control">
|
||||
<input type="checkbox" name="depreciation" value="1" @checked($template->checkmarkValue('depreciation')) />
|
||||
{{ trans('general.depreciation') }}
|
||||
</label>
|
||||
|
||||
<label class="form-control">
|
||||
<input type="checkbox" name="checkout_date" value="1" @checked($template->checkmarkValue('checkout_date')) />
|
||||
{{ trans('admin/hardware/table.checkout_date') }}
|
||||
|
|
49
tests/Feature/Authentication/LoginTest.php
Normal file
49
tests/Feature/Authentication/LoginTest.php
Normal file
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\Feature\Authentication;
|
||||
|
||||
use App\Models\User;
|
||||
use Tests\TestCase;
|
||||
|
||||
class LoginTest extends TestCase
|
||||
{
|
||||
public function testLogsFailedLoginAttempt()
|
||||
{
|
||||
User::factory()->create(['username' => 'username_here']);
|
||||
|
||||
$this->withServerVariables(['REMOTE_ADDR' => '127.0.0.100'])
|
||||
->post('/login', [
|
||||
'username' => 'username_here',
|
||||
'password' => 'not a real password',
|
||||
], [
|
||||
'User-Agent' => 'Some Custom User Agent',
|
||||
]);
|
||||
|
||||
$this->assertDatabaseHas('login_attempts', [
|
||||
'username' => 'username_here',
|
||||
'remote_ip' => '127.0.0.100',
|
||||
'user_agent' => 'Some Custom User Agent',
|
||||
'successful' => 0,
|
||||
]);
|
||||
}
|
||||
|
||||
public function testLogsSuccessfulLogin()
|
||||
{
|
||||
User::factory()->create(['username' => 'username_here']);
|
||||
|
||||
$this->withServerVariables(['REMOTE_ADDR' => '127.0.0.100'])
|
||||
->post('/login', [
|
||||
'username' => 'username_here',
|
||||
'password' => 'password',
|
||||
], [
|
||||
'User-Agent' => 'Some Custom User Agent',
|
||||
]);
|
||||
|
||||
$this->assertDatabaseHas('login_attempts', [
|
||||
'username' => 'username_here',
|
||||
'remote_ip' => '127.0.0.100',
|
||||
'user_agent' => 'Some Custom User Agent',
|
||||
'successful' => 1,
|
||||
]);
|
||||
}
|
||||
}
|
91
tests/Feature/Checkouts/Ui/BulkAssetCheckoutTest.php
Normal file
91
tests/Feature/Checkouts/Ui/BulkAssetCheckoutTest.php
Normal file
|
@ -0,0 +1,91 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\Feature\Checkouts\Ui;
|
||||
|
||||
use App\Mail\CheckoutAssetMail;
|
||||
use App\Models\Asset;
|
||||
use App\Models\User;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use PHPUnit\Framework\ExpectationFailedException;
|
||||
use Tests\TestCase;
|
||||
|
||||
class BulkAssetCheckoutTest extends TestCase
|
||||
{
|
||||
public function testRequiresPermission()
|
||||
{
|
||||
$this->actingAs(User::factory()->create())
|
||||
->post(route('hardware.bulkcheckout.store'), [
|
||||
'selected_assets' => [1],
|
||||
'checkout_to_type' => 'user',
|
||||
'assigned_user' => 1,
|
||||
'assigned_asset' => null,
|
||||
'checkout_at' => null,
|
||||
'expected_checkin' => null,
|
||||
'note' => null,
|
||||
])
|
||||
->assertForbidden();
|
||||
}
|
||||
|
||||
public function testCanBulkCheckoutAssets()
|
||||
{
|
||||
Mail::fake();
|
||||
|
||||
$assets = Asset::factory()->requiresAcceptance()->count(2)->create();
|
||||
$user = User::factory()->create(['email' => 'someone@example.com']);
|
||||
|
||||
$checkoutAt = now()->subWeek()->format('Y-m-d');
|
||||
$expectedCheckin = now()->addWeek()->format('Y-m-d');
|
||||
|
||||
$this->actingAs(User::factory()->checkoutAssets()->viewAssets()->create())
|
||||
->followingRedirects()
|
||||
->post(route('hardware.bulkcheckout.store'), [
|
||||
'selected_assets' => $assets->pluck('id')->toArray(),
|
||||
'checkout_to_type' => 'user',
|
||||
'assigned_user' => $user->id,
|
||||
'assigned_asset' => null,
|
||||
'checkout_at' => $checkoutAt,
|
||||
'expected_checkin' => $expectedCheckin,
|
||||
'note' => null,
|
||||
])
|
||||
->assertOk();
|
||||
|
||||
$assets = $assets->fresh();
|
||||
|
||||
$assets->each(function ($asset) use ($expectedCheckin, $checkoutAt, $user) {
|
||||
$asset->assignedTo()->is($user);
|
||||
$asset->last_checkout = $checkoutAt;
|
||||
$asset->expected_checkin = $expectedCheckin;
|
||||
});
|
||||
|
||||
Mail::assertSent(CheckoutAssetMail::class, 2);
|
||||
Mail::assertSent(CheckoutAssetMail::class, function (CheckoutAssetMail $mail) {
|
||||
return $mail->hasTo('someone@example.com');
|
||||
});
|
||||
}
|
||||
|
||||
public function testHandleMissingModelBeingIncluded()
|
||||
{
|
||||
Mail::fake();
|
||||
|
||||
$this->actingAs(User::factory()->checkoutAssets()->create())
|
||||
->post(route('hardware.bulkcheckout.store'), [
|
||||
'selected_assets' => [
|
||||
Asset::factory()->requiresAcceptance()->create()->id,
|
||||
9999999,
|
||||
],
|
||||
'checkout_to_type' => 'user',
|
||||
'assigned_user' => User::factory()->create(['email' => 'someone@example.com'])->id,
|
||||
'assigned_asset' => null,
|
||||
'checkout_at' => null,
|
||||
'expected_checkin' => null,
|
||||
'note' => null,
|
||||
])
|
||||
->assertSessionHas('error', trans_choice('admin/hardware/message.multi-checkout.error', 2));
|
||||
|
||||
try {
|
||||
Mail::assertNotSent(CheckoutAssetMail::class);
|
||||
} catch (ExpectationFailedException $e) {
|
||||
$this->fail('Asset checkout email was sent when the entire checkout failed.');
|
||||
}
|
||||
}
|
||||
}
|
46
tests/Feature/Companies/Api/CreateCompaniesTest.php
Normal file
46
tests/Feature/Companies/Api/CreateCompaniesTest.php
Normal file
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\Feature\Companies\Api;
|
||||
|
||||
use App\Models\User;
|
||||
use Tests\Concerns\TestsPermissionsRequirement;
|
||||
use Tests\TestCase;
|
||||
|
||||
class CreateCompaniesTest extends TestCase implements TestsPermissionsRequirement
|
||||
{
|
||||
public function testRequiresPermission()
|
||||
{
|
||||
$this->actingAsForApi(User::factory()->create())
|
||||
->postJson(route('api.companies.store'))
|
||||
->assertForbidden();
|
||||
}
|
||||
|
||||
public function testValidationForCreatingCompany()
|
||||
{
|
||||
$this->actingAsForApi(User::factory()->createCompanies()->create())
|
||||
->postJson(route('api.companies.store'))
|
||||
->assertStatus(200)
|
||||
->assertStatusMessageIs('error')
|
||||
->assertJsonStructure([
|
||||
'messages' => [
|
||||
'name',
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public function testCanCreateCompany()
|
||||
{
|
||||
$this->actingAsForApi(User::factory()->createCompanies()->create())
|
||||
->postJson(route('api.companies.store'), [
|
||||
'name' => 'My Cool Company',
|
||||
'notes' => 'A Cool Note',
|
||||
])
|
||||
->assertStatus(200)
|
||||
->assertStatusMessageIs('success');
|
||||
|
||||
$this->assertDatabaseHas('companies', [
|
||||
'name' => 'My Cool Company',
|
||||
'notes' => 'A Cool Note',
|
||||
]);
|
||||
}
|
||||
}
|
53
tests/Feature/Companies/Api/UpdateCompaniesTest.php
Normal file
53
tests/Feature/Companies/Api/UpdateCompaniesTest.php
Normal file
|
@ -0,0 +1,53 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\Feature\Companies\Api;
|
||||
|
||||
use App\Models\Company;
|
||||
use App\Models\User;
|
||||
use Tests\TestCase;
|
||||
|
||||
class UpdateCompaniesTest extends TestCase
|
||||
{
|
||||
public function testRequiresPermissionToPatchCompany()
|
||||
{
|
||||
$company = Company::factory()->create();
|
||||
|
||||
$this->actingAsForApi(User::factory()->create())
|
||||
->patchJson(route('api.companies.update', $company))
|
||||
->assertForbidden();
|
||||
}
|
||||
|
||||
public function testValidationForPatchingCompany()
|
||||
{
|
||||
$company = Company::factory()->create();
|
||||
|
||||
$this->actingAsForApi(User::factory()->editCompanies()->create())
|
||||
->patchJson(route('api.companies.update', ['company' => $company->id]), [
|
||||
'name' => '',
|
||||
])
|
||||
->assertStatus(200)
|
||||
->assertStatusMessageIs('error')
|
||||
->assertJsonStructure([
|
||||
'messages' => [
|
||||
'name',
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public function testCanPatchCompany()
|
||||
{
|
||||
$company = Company::factory()->create();
|
||||
|
||||
$this->actingAsForApi(User::factory()->editCompanies()->create())
|
||||
->patchJson(route('api.companies.update', ['company' => $company->id]), [
|
||||
'name' => 'A Changed Name',
|
||||
'notes' => 'A Changed Note',
|
||||
])
|
||||
->assertStatus(200)
|
||||
->assertStatusMessageIs('success');
|
||||
|
||||
$company->refresh();
|
||||
$this->assertEquals('A Changed Name', $company->name);
|
||||
$this->assertEquals('A Changed Note', $company->notes);
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue