mirror of
https://github.com/snipe/snipe-it.git
synced 2024-11-09 23:24:06 -08:00
Merge branch 'develop' into laravel_v9
This commit is contained in:
commit
381890b578
|
@ -2889,6 +2889,24 @@
|
||||||
"avatar_url": "https://avatars.githubusercontent.com/u/570639?v=4",
|
"avatar_url": "https://avatars.githubusercontent.com/u/570639?v=4",
|
||||||
"profile": "https://github.com/Mezzle",
|
"profile": "https://github.com/Mezzle",
|
||||||
"contributions": []
|
"contributions": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "dboth",
|
||||||
|
"name": "dboth",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/5731963?v=4",
|
||||||
|
"profile": "http://dboth.de",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "zacharyfleck",
|
||||||
|
"name": "Zachary Fleck",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/87536651?v=4",
|
||||||
|
"profile": "https://github.com/zacharyfleck",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
2
.github/workflows/docker-alpine.yml
vendored
2
.github/workflows/docker-alpine.yml
vendored
|
@ -76,7 +76,7 @@ jobs:
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
file: ./Dockerfile.alpine
|
file: ./Dockerfile.alpine
|
||||||
platforms: linux/amd64
|
platforms: linux/amd64,linux/arm64
|
||||||
# For pull requests, we run the Docker build (to ensure no PR changes break the build),
|
# For pull requests, we run the Docker build (to ensure no PR changes break the build),
|
||||||
# but we ONLY do an image push to DockerHub if it's NOT a PR
|
# but we ONLY do an image push to DockerHub if it's NOT a PR
|
||||||
push: ${{ github.event_name != 'pull_request' }}
|
push: ${{ github.event_name != 'pull_request' }}
|
||||||
|
|
2
.github/workflows/docker.yml
vendored
2
.github/workflows/docker.yml
vendored
|
@ -76,7 +76,7 @@ jobs:
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
file: ./Dockerfile
|
file: ./Dockerfile
|
||||||
platforms: linux/amd64
|
platforms: linux/amd64,linux/arm64
|
||||||
# For pull requests, we run the Docker build (to ensure no PR changes break the build),
|
# For pull requests, we run the Docker build (to ensure no PR changes break the build),
|
||||||
# but we ONLY do an image push to DockerHub if it's NOT a PR
|
# but we ONLY do an image push to DockerHub if it's NOT a PR
|
||||||
push: ${{ github.event_name != 'pull_request' }}
|
push: ${{ github.event_name != 'pull_request' }}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
![Build Status](https://app.chipperci.com/projects/0e5f8979-31eb-4ee6-9abf-050b76ab0383/status/master) [![Crowdin](https://d322cqt584bo4o.cloudfront.net/snipe-it/localized.svg)](https://crowdin.com/project/snipe-it) [![Docker Pulls](https://img.shields.io/docker/pulls/snipe/snipe-it.svg)](https://hub.docker.com/r/snipe/snipe-it/) [![Twitter Follow](https://img.shields.io/twitter/follow/snipeitapp.svg?style=social)](https://twitter.com/snipeitapp) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/553ce52037fc43ea99149785afcfe641)](https://www.codacy.com/app/snipe/snipe-it?utm_source=github.com&utm_medium=referral&utm_content=snipe/snipe-it&utm_campaign=Badge_Grade)
|
![Build Status](https://app.chipperci.com/projects/0e5f8979-31eb-4ee6-9abf-050b76ab0383/status/master) [![Crowdin](https://d322cqt584bo4o.cloudfront.net/snipe-it/localized.svg)](https://crowdin.com/project/snipe-it) [![Docker Pulls](https://img.shields.io/docker/pulls/snipe/snipe-it.svg)](https://hub.docker.com/r/snipe/snipe-it/) [![Twitter Follow](https://img.shields.io/twitter/follow/snipeitapp.svg?style=social)](https://twitter.com/snipeitapp) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/553ce52037fc43ea99149785afcfe641)](https://www.codacy.com/app/snipe/snipe-it?utm_source=github.com&utm_medium=referral&utm_content=snipe/snipe-it&utm_campaign=Badge_Grade)
|
||||||
[![All Contributors](https://img.shields.io/badge/all_contributors-318-orange.svg?style=flat-square)](#contributors) [![Discord](https://badgen.net/badge/icon/discord?icon=discord&label)](https://discord.gg/yZFtShAcKk) [![huntr](https://cdn.huntr.dev/huntr_security_badge_mono.svg)](https://huntr.dev)
|
[![All Contributors](https://img.shields.io/badge/all_contributors-320-orange.svg?style=flat-square)](#contributors) [![Discord](https://badgen.net/badge/icon/discord?icon=discord&label)](https://discord.gg/yZFtShAcKk) [![huntr](https://cdn.huntr.dev/huntr_security_badge_mono.svg)](https://huntr.dev)
|
||||||
|
|
||||||
## Snipe-IT - Open Source Asset Management System
|
## Snipe-IT - Open Source Asset Management System
|
||||||
|
|
||||||
|
@ -144,7 +144,7 @@ Thanks goes to all of these wonderful people ([emoji key](https://github.com/ken
|
||||||
| [<img src="https://avatars.githubusercontent.com/u/32363424?v=4" width="110px;"/><br /><sub>Peace</sub>](https://github.com/julian-piehl)<br />[💻](https://github.com/snipe/snipe-it/commits?author=julian-piehl "Code") | [<img src="https://avatars.githubusercontent.com/u/231528?v=4" width="110px;"/><br /><sub>Kyle Gordon</sub>](https://github.com/kylegordon)<br />[💻](https://github.com/snipe/snipe-it/commits?author=kylegordon "Code") | [<img src="https://avatars.githubusercontent.com/u/53009155?v=4" width="110px;"/><br /><sub>Katharina Drexel</sub>](http://www.bfh.ch)<br />[💻](https://github.com/snipe/snipe-it/commits?author=sunflowerbofh "Code") | [<img src="https://avatars.githubusercontent.com/u/1931963?v=4" width="110px;"/><br /><sub>David Sferruzza</sub>](https://david.sferruzza.fr/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=dsferruzza "Code") | [<img src="https://avatars.githubusercontent.com/u/19511639?v=4" width="110px;"/><br /><sub>Rick Nelson</sub>](https://github.com/rnelsonee)<br />[💻](https://github.com/snipe/snipe-it/commits?author=rnelsonee "Code") | [<img src="https://avatars.githubusercontent.com/u/94169344?v=4" width="110px;"/><br /><sub>BasO12</sub>](https://github.com/BasO12)<br />[💻](https://github.com/snipe/snipe-it/commits?author=BasO12 "Code") | [<img src="https://avatars.githubusercontent.com/u/111710123?v=4" width="110px;"/><br /><sub>Vautia</sub>](https://github.com/Vautia)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Vautia "Code") |
|
| [<img src="https://avatars.githubusercontent.com/u/32363424?v=4" width="110px;"/><br /><sub>Peace</sub>](https://github.com/julian-piehl)<br />[💻](https://github.com/snipe/snipe-it/commits?author=julian-piehl "Code") | [<img src="https://avatars.githubusercontent.com/u/231528?v=4" width="110px;"/><br /><sub>Kyle Gordon</sub>](https://github.com/kylegordon)<br />[💻](https://github.com/snipe/snipe-it/commits?author=kylegordon "Code") | [<img src="https://avatars.githubusercontent.com/u/53009155?v=4" width="110px;"/><br /><sub>Katharina Drexel</sub>](http://www.bfh.ch)<br />[💻](https://github.com/snipe/snipe-it/commits?author=sunflowerbofh "Code") | [<img src="https://avatars.githubusercontent.com/u/1931963?v=4" width="110px;"/><br /><sub>David Sferruzza</sub>](https://david.sferruzza.fr/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=dsferruzza "Code") | [<img src="https://avatars.githubusercontent.com/u/19511639?v=4" width="110px;"/><br /><sub>Rick Nelson</sub>](https://github.com/rnelsonee)<br />[💻](https://github.com/snipe/snipe-it/commits?author=rnelsonee "Code") | [<img src="https://avatars.githubusercontent.com/u/94169344?v=4" width="110px;"/><br /><sub>BasO12</sub>](https://github.com/BasO12)<br />[💻](https://github.com/snipe/snipe-it/commits?author=BasO12 "Code") | [<img src="https://avatars.githubusercontent.com/u/111710123?v=4" width="110px;"/><br /><sub>Vautia</sub>](https://github.com/Vautia)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Vautia "Code") |
|
||||||
| [<img src="https://avatars.githubusercontent.com/u/28321?v=4" width="110px;"/><br /><sub>Chris Hartjes</sub>](http://www.littlehart.net/atthekeyboard)<br />[💻](https://github.com/snipe/snipe-it/commits?author=chartjes "Code") | [<img src="https://avatars.githubusercontent.com/u/2404584?v=4" width="110px;"/><br /><sub>geo-chen</sub>](https://github.com/geo-chen)<br />[💻](https://github.com/snipe/snipe-it/commits?author=geo-chen "Code") | [<img src="https://avatars.githubusercontent.com/u/6006620?v=4" width="110px;"/><br /><sub>Phan Nguyen</sub>](https://github.com/nh314)<br />[💻](https://github.com/snipe/snipe-it/commits?author=nh314 "Code") | [<img src="https://avatars.githubusercontent.com/u/115993812?v=4" width="110px;"/><br /><sub>Iisakki Jaakkola</sub>](https://github.com/StarlessNights)<br />[💻](https://github.com/snipe/snipe-it/commits?author=StarlessNights "Code") | [<img src="https://avatars.githubusercontent.com/u/22633385?v=4" width="110px;"/><br /><sub>Ikko Ashimine</sub>](https://bandism.net/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=eltociear "Code") | [<img src="https://avatars.githubusercontent.com/u/56871540?v=4" width="110px;"/><br /><sub>Lukas Fehling</sub>](https://github.com/lukasfehling)<br />[💻](https://github.com/snipe/snipe-it/commits?author=lukasfehling "Code") | [<img src="https://avatars.githubusercontent.com/u/1975990?v=4" width="110px;"/><br /><sub>Fernando Almeida</sub>](https://github.com/fernando-almeida)<br />[💻](https://github.com/snipe/snipe-it/commits?author=fernando-almeida "Code") |
|
| [<img src="https://avatars.githubusercontent.com/u/28321?v=4" width="110px;"/><br /><sub>Chris Hartjes</sub>](http://www.littlehart.net/atthekeyboard)<br />[💻](https://github.com/snipe/snipe-it/commits?author=chartjes "Code") | [<img src="https://avatars.githubusercontent.com/u/2404584?v=4" width="110px;"/><br /><sub>geo-chen</sub>](https://github.com/geo-chen)<br />[💻](https://github.com/snipe/snipe-it/commits?author=geo-chen "Code") | [<img src="https://avatars.githubusercontent.com/u/6006620?v=4" width="110px;"/><br /><sub>Phan Nguyen</sub>](https://github.com/nh314)<br />[💻](https://github.com/snipe/snipe-it/commits?author=nh314 "Code") | [<img src="https://avatars.githubusercontent.com/u/115993812?v=4" width="110px;"/><br /><sub>Iisakki Jaakkola</sub>](https://github.com/StarlessNights)<br />[💻](https://github.com/snipe/snipe-it/commits?author=StarlessNights "Code") | [<img src="https://avatars.githubusercontent.com/u/22633385?v=4" width="110px;"/><br /><sub>Ikko Ashimine</sub>](https://bandism.net/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=eltociear "Code") | [<img src="https://avatars.githubusercontent.com/u/56871540?v=4" width="110px;"/><br /><sub>Lukas Fehling</sub>](https://github.com/lukasfehling)<br />[💻](https://github.com/snipe/snipe-it/commits?author=lukasfehling "Code") | [<img src="https://avatars.githubusercontent.com/u/1975990?v=4" width="110px;"/><br /><sub>Fernando Almeida</sub>](https://github.com/fernando-almeida)<br />[💻](https://github.com/snipe/snipe-it/commits?author=fernando-almeida "Code") |
|
||||||
| [<img src="https://avatars.githubusercontent.com/u/116301219?v=4" width="110px;"/><br /><sub>akemidx</sub>](https://github.com/akemidx)<br />[💻](https://github.com/snipe/snipe-it/commits?author=akemidx "Code") | [<img src="https://avatars.githubusercontent.com/u/144778?v=4" width="110px;"/><br /><sub>Oguz Bilgic</sub>](http://oguz.site)<br />[💻](https://github.com/snipe/snipe-it/commits?author=oguzbilgic "Code") | [<img src="https://avatars.githubusercontent.com/u/9262438?v=4" width="110px;"/><br /><sub>Scooter Crawford</sub>](https://github.com/scoo73r)<br />[💻](https://github.com/snipe/snipe-it/commits?author=scoo73r "Code") | [<img src="https://avatars.githubusercontent.com/u/5957345?v=4" width="110px;"/><br /><sub>subdriven</sub>](https://github.com/subdriven)<br />[💻](https://github.com/snipe/snipe-it/commits?author=subdriven "Code") | [<img src="https://avatars.githubusercontent.com/u/658865?v=4" width="110px;"/><br /><sub>Andrew Savinykh</sub>](https://github.com/AndrewSav)<br />[💻](https://github.com/snipe/snipe-it/commits?author=AndrewSav "Code") | [<img src="https://avatars.githubusercontent.com/u/1155067?v=4" width="110px;"/><br /><sub>Tadayuki Onishi</sub>](https://kenchan0130.github.io)<br />[💻](https://github.com/snipe/snipe-it/commits?author=kenchan0130 "Code") | [<img src="https://avatars.githubusercontent.com/u/112496896?v=4" width="110px;"/><br /><sub>Florian</sub>](https://github.com/floschoepfer)<br />[💻](https://github.com/snipe/snipe-it/commits?author=floschoepfer "Code") |
|
| [<img src="https://avatars.githubusercontent.com/u/116301219?v=4" width="110px;"/><br /><sub>akemidx</sub>](https://github.com/akemidx)<br />[💻](https://github.com/snipe/snipe-it/commits?author=akemidx "Code") | [<img src="https://avatars.githubusercontent.com/u/144778?v=4" width="110px;"/><br /><sub>Oguz Bilgic</sub>](http://oguz.site)<br />[💻](https://github.com/snipe/snipe-it/commits?author=oguzbilgic "Code") | [<img src="https://avatars.githubusercontent.com/u/9262438?v=4" width="110px;"/><br /><sub>Scooter Crawford</sub>](https://github.com/scoo73r)<br />[💻](https://github.com/snipe/snipe-it/commits?author=scoo73r "Code") | [<img src="https://avatars.githubusercontent.com/u/5957345?v=4" width="110px;"/><br /><sub>subdriven</sub>](https://github.com/subdriven)<br />[💻](https://github.com/snipe/snipe-it/commits?author=subdriven "Code") | [<img src="https://avatars.githubusercontent.com/u/658865?v=4" width="110px;"/><br /><sub>Andrew Savinykh</sub>](https://github.com/AndrewSav)<br />[💻](https://github.com/snipe/snipe-it/commits?author=AndrewSav "Code") | [<img src="https://avatars.githubusercontent.com/u/1155067?v=4" width="110px;"/><br /><sub>Tadayuki Onishi</sub>](https://kenchan0130.github.io)<br />[💻](https://github.com/snipe/snipe-it/commits?author=kenchan0130 "Code") | [<img src="https://avatars.githubusercontent.com/u/112496896?v=4" width="110px;"/><br /><sub>Florian</sub>](https://github.com/floschoepfer)<br />[💻](https://github.com/snipe/snipe-it/commits?author=floschoepfer "Code") |
|
||||||
| [<img src="https://avatars.githubusercontent.com/u/7305753?v=4" width="110px;"/><br /><sub>Spencer Long</sub>](http://spencerlong.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=spencerrlongg "Code") | [<img src="https://avatars.githubusercontent.com/u/1141514?v=4" width="110px;"/><br /><sub>Marcus Moore</sub>](https://github.com/marcusmoore)<br />[💻](https://github.com/snipe/snipe-it/commits?author=marcusmoore "Code") | [<img src="https://avatars.githubusercontent.com/u/570639?v=4" width="110px;"/><br /><sub>Martin Meredith</sub>](https://github.com/Mezzle)<br /> |
|
| [<img src="https://avatars.githubusercontent.com/u/7305753?v=4" width="110px;"/><br /><sub>Spencer Long</sub>](http://spencerlong.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=spencerrlongg "Code") | [<img src="https://avatars.githubusercontent.com/u/1141514?v=4" width="110px;"/><br /><sub>Marcus Moore</sub>](https://github.com/marcusmoore)<br />[💻](https://github.com/snipe/snipe-it/commits?author=marcusmoore "Code") | [<img src="https://avatars.githubusercontent.com/u/570639?v=4" width="110px;"/><br /><sub>Martin Meredith</sub>](https://github.com/Mezzle)<br /> | [<img src="https://avatars.githubusercontent.com/u/5731963?v=4" width="110px;"/><br /><sub>dboth</sub>](http://dboth.de)<br />[💻](https://github.com/snipe/snipe-it/commits?author=dboth "Code") | [<img src="https://avatars.githubusercontent.com/u/87536651?v=4" width="110px;"/><br /><sub>Zachary Fleck</sub>](https://github.com/zacharyfleck)<br />[💻](https://github.com/snipe/snipe-it/commits?author=zacharyfleck "Code") |
|
||||||
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
||||||
|
|
||||||
This project follows the [all-contributors](https://github.com/kentcdodds/all-contributors) specification. Contributions of any kind welcome!
|
This project follows the [all-contributors](https://github.com/kentcdodds/all-contributors) specification. Contributions of any kind welcome!
|
||||||
|
|
|
@ -56,7 +56,7 @@ class CheckoutLicenseToAllUsers extends Command
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$users = User::whereNull('deleted_at')->where('autoassign_licenses', '==', 1)->with('licenses')->get();
|
$users = User::whereNull('deleted_at')->where('autoassign_licenses', '=', 1)->with('licenses')->get();
|
||||||
|
|
||||||
if ($users->count() > $license->getAvailSeatsCountAttribute()) {
|
if ($users->count() > $license->getAvailSeatsCountAttribute()) {
|
||||||
$this->info('You do not have enough free seats to complete this task, so we will check out as many as we can. ');
|
$this->info('You do not have enough free seats to complete this task, so we will check out as many as we can. ');
|
||||||
|
|
|
@ -20,13 +20,14 @@ class CreateAdmin extends Command
|
||||||
* @property string $password
|
* @property string $password
|
||||||
* @property boolean $activated
|
* @property boolean $activated
|
||||||
* @property boolean $show_in_list
|
* @property boolean $show_in_list
|
||||||
|
* @property boolean $autoassign_licenses
|
||||||
* @property \Illuminate\Support\Carbon|null $created_at
|
* @property \Illuminate\Support\Carbon|null $created_at
|
||||||
* @property mixed $created_by
|
* @property mixed $created_by
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
protected $signature = 'snipeit:create-admin {--first_name=} {--last_name=} {--email=} {--username=} {--password=} {show_in_list?}';
|
protected $signature = 'snipeit:create-admin {--first_name=} {--last_name=} {--email=} {--username=} {--password=} {show_in_list?} {autoassign_licenses?}';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The console command description.
|
* The console command description.
|
||||||
|
@ -54,6 +55,9 @@ class CreateAdmin extends Command
|
||||||
$email = $this->option('email');
|
$email = $this->option('email');
|
||||||
$password = $this->option('password');
|
$password = $this->option('password');
|
||||||
$show_in_list = $this->argument('show_in_list');
|
$show_in_list = $this->argument('show_in_list');
|
||||||
|
$autoassign_licenses = $this->argument('autoassign_licenses');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (($first_name == '') || ($last_name == '') || ($username == '') || ($email == '') || ($password == '')) {
|
if (($first_name == '') || ($last_name == '') || ($username == '') || ($email == '') || ($password == '')) {
|
||||||
$this->info('ERROR: All fields are required.');
|
$this->info('ERROR: All fields are required.');
|
||||||
|
@ -70,6 +74,11 @@ class CreateAdmin extends Command
|
||||||
if ($show_in_list == 'false') {
|
if ($show_in_list == 'false') {
|
||||||
$user->show_in_list = 0;
|
$user->show_in_list = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($autoassign_licenses == 'false') {
|
||||||
|
$user->autoassign_licenses = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if ($user->save()) {
|
if ($user->save()) {
|
||||||
$this->info('New user created');
|
$this->info('New user created');
|
||||||
$user->groups()->attach(1);
|
$user->groups()->attach(1);
|
||||||
|
|
|
@ -62,6 +62,7 @@ class LdapSync extends Command
|
||||||
$ldap_result_phone = Setting::getSettings()->ldap_phone_field;
|
$ldap_result_phone = Setting::getSettings()->ldap_phone_field;
|
||||||
$ldap_result_jobtitle = Setting::getSettings()->ldap_jobtitle;
|
$ldap_result_jobtitle = Setting::getSettings()->ldap_jobtitle;
|
||||||
$ldap_result_country = Setting::getSettings()->ldap_country;
|
$ldap_result_country = Setting::getSettings()->ldap_country;
|
||||||
|
$ldap_result_location = Setting::getSettings()->ldap_location;
|
||||||
$ldap_result_dept = Setting::getSettings()->ldap_dept;
|
$ldap_result_dept = Setting::getSettings()->ldap_dept;
|
||||||
$ldap_result_manager = Setting::getSettings()->ldap_manager;
|
$ldap_result_manager = Setting::getSettings()->ldap_manager;
|
||||||
$ldap_default_group = Setting::getSettings()->ldap_default_group;
|
$ldap_default_group = Setting::getSettings()->ldap_default_group;
|
||||||
|
@ -209,8 +210,11 @@ class LdapSync extends Command
|
||||||
$item['country'] = $results[$i][$ldap_result_country][0] ?? '';
|
$item['country'] = $results[$i][$ldap_result_country][0] ?? '';
|
||||||
$item['department'] = $results[$i][$ldap_result_dept][0] ?? '';
|
$item['department'] = $results[$i][$ldap_result_dept][0] ?? '';
|
||||||
$item['manager'] = $results[$i][$ldap_result_manager][0] ?? '';
|
$item['manager'] = $results[$i][$ldap_result_manager][0] ?? '';
|
||||||
|
$item['location'] = $results[$i][$ldap_result_location][0] ?? '';
|
||||||
|
|
||||||
|
$location = Location::firstOrCreate([
|
||||||
|
'name' => $item['location'],
|
||||||
|
]);
|
||||||
$department = Department::firstOrCreate([
|
$department = Department::firstOrCreate([
|
||||||
'name' => $item['department'],
|
'name' => $item['department'],
|
||||||
]);
|
]);
|
||||||
|
@ -236,6 +240,7 @@ class LdapSync extends Command
|
||||||
$user->jobtitle = $item['jobtitle'];
|
$user->jobtitle = $item['jobtitle'];
|
||||||
$user->country = $item['country'];
|
$user->country = $item['country'];
|
||||||
$user->department_id = $department->id;
|
$user->department_id = $department->id;
|
||||||
|
$user->location_id = $location->id;
|
||||||
|
|
||||||
if($item['manager'] != null) {
|
if($item['manager'] != null) {
|
||||||
// Check Cache first
|
// Check Cache first
|
||||||
|
|
|
@ -77,7 +77,7 @@ class AccessoriesController extends Controller
|
||||||
$accessory->manufacturer_id = request('manufacturer_id');
|
$accessory->manufacturer_id = request('manufacturer_id');
|
||||||
$accessory->model_number = request('model_number');
|
$accessory->model_number = request('model_number');
|
||||||
$accessory->purchase_date = request('purchase_date');
|
$accessory->purchase_date = request('purchase_date');
|
||||||
$accessory->purchase_cost = Helper::ParseCurrency(request('purchase_cost'));
|
$accessory->purchase_cost = request('purchase_cost');
|
||||||
$accessory->qty = request('qty');
|
$accessory->qty = request('qty');
|
||||||
$accessory->user_id = Auth::user()->id;
|
$accessory->user_id = Auth::user()->id;
|
||||||
$accessory->supplier_id = request('supplier_id');
|
$accessory->supplier_id = request('supplier_id');
|
||||||
|
@ -180,7 +180,7 @@ class AccessoriesController extends Controller
|
||||||
$accessory->order_number = request('order_number');
|
$accessory->order_number = request('order_number');
|
||||||
$accessory->model_number = request('model_number');
|
$accessory->model_number = request('model_number');
|
||||||
$accessory->purchase_date = request('purchase_date');
|
$accessory->purchase_date = request('purchase_date');
|
||||||
$accessory->purchase_cost = Helper::ParseCurrency(request('purchase_cost'));
|
$accessory->purchase_cost = request('purchase_cost');
|
||||||
$accessory->qty = request('qty');
|
$accessory->qty = request('qty');
|
||||||
$accessory->supplier_id = request('supplier_id');
|
$accessory->supplier_id = request('supplier_id');
|
||||||
$accessory->notes = request('notes');
|
$accessory->notes = request('notes');
|
||||||
|
|
|
@ -118,7 +118,7 @@ class AssetMaintenancesController extends Controller
|
||||||
$assetMaintenance = new AssetMaintenance();
|
$assetMaintenance = new AssetMaintenance();
|
||||||
$assetMaintenance->supplier_id = $request->input('supplier_id');
|
$assetMaintenance->supplier_id = $request->input('supplier_id');
|
||||||
$assetMaintenance->is_warranty = $request->input('is_warranty');
|
$assetMaintenance->is_warranty = $request->input('is_warranty');
|
||||||
$assetMaintenance->cost = Helper::ParseCurrency($request->input('cost'));
|
$assetMaintenance->cost = $request->input('cost');
|
||||||
$assetMaintenance->notes = e($request->input('notes'));
|
$assetMaintenance->notes = e($request->input('notes'));
|
||||||
$asset = Asset::find(e($request->input('asset_id')));
|
$asset = Asset::find(e($request->input('asset_id')));
|
||||||
|
|
||||||
|
@ -175,7 +175,7 @@ class AssetMaintenancesController extends Controller
|
||||||
|
|
||||||
$assetMaintenance->supplier_id = e($request->input('supplier_id'));
|
$assetMaintenance->supplier_id = e($request->input('supplier_id'));
|
||||||
$assetMaintenance->is_warranty = e($request->input('is_warranty'));
|
$assetMaintenance->is_warranty = e($request->input('is_warranty'));
|
||||||
$assetMaintenance->cost = Helper::ParseCurrency($request->input('cost'));
|
$assetMaintenance->cost = $request->input('cost');
|
||||||
$assetMaintenance->notes = e($request->input('notes'));
|
$assetMaintenance->notes = e($request->input('notes'));
|
||||||
|
|
||||||
$asset = Asset::find(request('asset_id'));
|
$asset = Asset::find(request('asset_id'));
|
||||||
|
|
|
@ -550,7 +550,8 @@ class AssetsController extends Controller
|
||||||
$asset->depreciate = '0';
|
$asset->depreciate = '0';
|
||||||
$asset->status_id = $request->get('status_id', 0);
|
$asset->status_id = $request->get('status_id', 0);
|
||||||
$asset->warranty_months = $request->get('warranty_months', null);
|
$asset->warranty_months = $request->get('warranty_months', null);
|
||||||
$asset->purchase_cost = Helper::ParseCurrency($request->get('purchase_cost')); // this is the API's store method, so I don't know that I want to do this? Confusing. FIXME (or not?!)
|
$asset->purchase_cost = $request->get('purchase_cost');
|
||||||
|
$asset->asset_eol_date = $request->get('asset_eol_date', $asset->present()->eol_date());
|
||||||
$asset->purchase_date = $request->get('purchase_date', null);
|
$asset->purchase_date = $request->get('purchase_date', null);
|
||||||
$asset->assigned_to = $request->get('assigned_to', null);
|
$asset->assigned_to = $request->get('assigned_to', null);
|
||||||
$asset->supplier_id = $request->get('supplier_id');
|
$asset->supplier_id = $request->get('supplier_id');
|
||||||
|
@ -558,6 +559,7 @@ class AssetsController extends Controller
|
||||||
$asset->rtd_location_id = $request->get('rtd_location_id', null);
|
$asset->rtd_location_id = $request->get('rtd_location_id', null);
|
||||||
$asset->location_id = $request->get('rtd_location_id', null);
|
$asset->location_id = $request->get('rtd_location_id', null);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* this is here just legacy reasons. Api\AssetController
|
* this is here just legacy reasons. Api\AssetController
|
||||||
* used image_source once to allow encoded image uploads.
|
* used image_source once to allow encoded image uploads.
|
||||||
|
|
|
@ -23,10 +23,10 @@ class ManufacturersController extends Controller
|
||||||
public function index(Request $request)
|
public function index(Request $request)
|
||||||
{
|
{
|
||||||
$this->authorize('view', Manufacturer::class);
|
$this->authorize('view', Manufacturer::class);
|
||||||
$allowed_columns = ['id', 'name', 'url', 'support_url', 'support_email', 'support_phone', 'created_at', 'updated_at', 'image', 'assets_count', 'consumables_count', 'components_count', 'licenses_count'];
|
$allowed_columns = ['id', 'name', 'url', 'support_url', 'support_email', 'warranty_lookup_url', 'support_phone', 'created_at', 'updated_at', 'image', 'assets_count', 'consumables_count', 'components_count', 'licenses_count'];
|
||||||
|
|
||||||
$manufacturers = Manufacturer::select(
|
$manufacturers = Manufacturer::select(
|
||||||
['id', 'name', 'url', 'support_url', 'support_email', 'support_phone', 'created_at', 'updated_at', 'image', 'deleted_at']
|
['id', 'name', 'url', 'support_url', 'warranty_lookup_url', 'support_email', 'support_phone', 'created_at', 'updated_at', 'image', 'deleted_at']
|
||||||
)->withCount('assets as assets_count')->withCount('licenses as licenses_count')->withCount('consumables as consumables_count')->withCount('accessories as accessories_count');
|
)->withCount('assets as assets_count')->withCount('licenses as licenses_count')->withCount('consumables as consumables_count')->withCount('accessories as accessories_count');
|
||||||
|
|
||||||
if ($request->input('deleted') == 'true') {
|
if ($request->input('deleted') == 'true') {
|
||||||
|
@ -49,6 +49,10 @@ class ManufacturersController extends Controller
|
||||||
$manufacturers->where('support_url', '=', $request->input('support_url'));
|
$manufacturers->where('support_url', '=', $request->input('support_url'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($request->filled('warranty_lookup_url')) {
|
||||||
|
$manufacturers->where('warranty_lookup_url', '=', $request->input('warranty_lookup_url'));
|
||||||
|
}
|
||||||
|
|
||||||
if ($request->filled('support_phone')) {
|
if ($request->filled('support_phone')) {
|
||||||
$manufacturers->where('support_phone', '=', $request->input('support_phone'));
|
$manufacturers->where('support_phone', '=', $request->input('support_phone'));
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,6 +71,7 @@ class UsersController extends Controller
|
||||||
'users.start_date',
|
'users.start_date',
|
||||||
'users.end_date',
|
'users.end_date',
|
||||||
'users.vip',
|
'users.vip',
|
||||||
|
'users.autoassign_licenses',
|
||||||
|
|
||||||
])->with('manager', 'groups', 'userloc', 'company', 'department', 'assets', 'licenses', 'accessories', 'consumables', 'createdBy',)
|
])->with('manager', 'groups', 'userloc', 'company', 'department', 'assets', 'licenses', 'accessories', 'consumables', 'createdBy',)
|
||||||
->withCount('assets as assets_count', 'licenses as licenses_count', 'accessories as accessories_count', 'consumables as consumables_count');
|
->withCount('assets as assets_count', 'licenses as licenses_count', 'accessories as accessories_count', 'consumables as consumables_count');
|
||||||
|
@ -187,6 +188,10 @@ class UsersController extends Controller
|
||||||
$users->has('accessories', '=', $request->input('accessories_count'));
|
$users->has('accessories', '=', $request->input('accessories_count'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($request->filled('autoassign_licenses')) {
|
||||||
|
$users->where('autoassign_licenses', '=', $request->input('autoassign_licenses'));
|
||||||
|
}
|
||||||
|
|
||||||
if ($request->filled('search')) {
|
if ($request->filled('search')) {
|
||||||
$users = $users->TextSearch($request->input('search'));
|
$users = $users->TextSearch($request->input('search'));
|
||||||
}
|
}
|
||||||
|
@ -259,6 +264,7 @@ class UsersController extends Controller
|
||||||
'vip',
|
'vip',
|
||||||
'start_date',
|
'start_date',
|
||||||
'end_date',
|
'end_date',
|
||||||
|
'autoassign_licenses',
|
||||||
];
|
];
|
||||||
|
|
||||||
$sort = in_array($request->get('sort'), $allowed_columns) ? $request->get('sort') : 'first_name';
|
$sort = in_array($request->get('sort'), $allowed_columns) ? $request->get('sort') : 'first_name';
|
||||||
|
@ -356,7 +362,7 @@ class UsersController extends Controller
|
||||||
$user->permissions = $permissions_array;
|
$user->permissions = $permissions_array;
|
||||||
}
|
}
|
||||||
|
|
||||||
$tmp_pass = substr(str_shuffle('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'), 0, 20);
|
$tmp_pass = substr(str_shuffle('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'), 0, 40);
|
||||||
$user->password = bcrypt($request->get('password', $tmp_pass));
|
$user->password = bcrypt($request->get('password', $tmp_pass));
|
||||||
|
|
||||||
app('App\Http\Requests\ImageUploadRequest')->handleImages($user, 600, 'image', 'avatars', 'avatar');
|
app('App\Http\Requests\ImageUploadRequest')->handleImages($user, 600, 'image', 'avatars', 'avatar');
|
||||||
|
|
|
@ -101,7 +101,7 @@ class AssetMaintenancesController extends Controller
|
||||||
$assetMaintenance = new AssetMaintenance();
|
$assetMaintenance = new AssetMaintenance();
|
||||||
$assetMaintenance->supplier_id = $request->input('supplier_id');
|
$assetMaintenance->supplier_id = $request->input('supplier_id');
|
||||||
$assetMaintenance->is_warranty = $request->input('is_warranty');
|
$assetMaintenance->is_warranty = $request->input('is_warranty');
|
||||||
$assetMaintenance->cost = Helper::ParseCurrency($request->input('cost'));
|
$assetMaintenance->cost = $request->input('cost');
|
||||||
$assetMaintenance->notes = $request->input('notes');
|
$assetMaintenance->notes = $request->input('notes');
|
||||||
$asset = Asset::find($request->input('asset_id'));
|
$asset = Asset::find($request->input('asset_id'));
|
||||||
|
|
||||||
|
@ -211,7 +211,7 @@ class AssetMaintenancesController extends Controller
|
||||||
|
|
||||||
$assetMaintenance->supplier_id = $request->input('supplier_id');
|
$assetMaintenance->supplier_id = $request->input('supplier_id');
|
||||||
$assetMaintenance->is_warranty = $request->input('is_warranty');
|
$assetMaintenance->is_warranty = $request->input('is_warranty');
|
||||||
$assetMaintenance->cost = Helper::ParseCurrency($request->input('cost'));
|
$assetMaintenance->cost = $request->input('cost');
|
||||||
$assetMaintenance->notes = $request->input('notes');
|
$assetMaintenance->notes = $request->input('notes');
|
||||||
|
|
||||||
$asset = Asset::find(request('asset_id'));
|
$asset = Asset::find(request('asset_id'));
|
||||||
|
|
|
@ -140,9 +140,9 @@ class AssetsController extends Controller
|
||||||
$asset->depreciate = '0';
|
$asset->depreciate = '0';
|
||||||
$asset->status_id = request('status_id');
|
$asset->status_id = request('status_id');
|
||||||
$asset->warranty_months = request('warranty_months', null);
|
$asset->warranty_months = request('warranty_months', null);
|
||||||
$asset->purchase_cost = Helper::ParseCurrency($request->get('purchase_cost'));
|
$asset->purchase_cost = request('purchase_cost');
|
||||||
$asset->purchase_date = request('purchase_date', null);
|
$asset->purchase_date = request('purchase_date', null);
|
||||||
$asset->asset_eol_date = request('asset_eol_date', null);
|
$asset->asset_eol_date = request('asset_eol_date', $asset->present()->eol_date());
|
||||||
$asset->assigned_to = request('assigned_to', null);
|
$asset->assigned_to = request('assigned_to', null);
|
||||||
$asset->supplier_id = request('supplier_id', null);
|
$asset->supplier_id = request('supplier_id', null);
|
||||||
$asset->requestable = request('requestable', 0);
|
$asset->requestable = request('requestable', 0);
|
||||||
|
@ -312,7 +312,7 @@ class AssetsController extends Controller
|
||||||
|
|
||||||
$asset->status_id = $request->input('status_id', null);
|
$asset->status_id = $request->input('status_id', null);
|
||||||
$asset->warranty_months = $request->input('warranty_months', null);
|
$asset->warranty_months = $request->input('warranty_months', null);
|
||||||
$asset->purchase_cost = Helper::ParseCurrency($request->input('purchase_cost', null));
|
$asset->purchase_cost = $request->input('purchase_cost', null);
|
||||||
$asset->asset_eol_date = request('asset_eol_date', null);
|
$asset->asset_eol_date = request('asset_eol_date', null);
|
||||||
|
|
||||||
$asset->purchase_date = $request->input('purchase_date', null);
|
$asset->purchase_date = $request->input('purchase_date', null);
|
||||||
|
|
|
@ -29,7 +29,7 @@ class BulkAssetsController extends Controller
|
||||||
*/
|
*/
|
||||||
public function edit(Request $request)
|
public function edit(Request $request)
|
||||||
{
|
{
|
||||||
$this->authorize('update', Asset::class);
|
$this->authorize('view', Asset::class);
|
||||||
|
|
||||||
if (! $request->filled('ids')) {
|
if (! $request->filled('ids')) {
|
||||||
return redirect()->back()->with('error', trans('admin/hardware/message.update.no_assets_selected'));
|
return redirect()->back()->with('error', trans('admin/hardware/message.update.no_assets_selected'));
|
||||||
|
@ -44,6 +44,7 @@ class BulkAssetsController extends Controller
|
||||||
if ($request->filled('bulk_actions')) {
|
if ($request->filled('bulk_actions')) {
|
||||||
switch ($request->input('bulk_actions')) {
|
switch ($request->input('bulk_actions')) {
|
||||||
case 'labels':
|
case 'labels':
|
||||||
|
$this->authorize('view', Asset::class);
|
||||||
return view('hardware/labels')
|
return view('hardware/labels')
|
||||||
->with('assets', Asset::find($asset_ids))
|
->with('assets', Asset::find($asset_ids))
|
||||||
->with('settings', Setting::getSettings())
|
->with('settings', Setting::getSettings())
|
||||||
|
@ -51,6 +52,7 @@ class BulkAssetsController extends Controller
|
||||||
->with('count', 0);
|
->with('count', 0);
|
||||||
|
|
||||||
case 'delete':
|
case 'delete':
|
||||||
|
$this->authorize('delete', Asset::class);
|
||||||
$assets = Asset::with('assignedTo', 'location')->find($asset_ids);
|
$assets = Asset::with('assignedTo', 'location')->find($asset_ids);
|
||||||
$assets->each(function ($asset) {
|
$assets->each(function ($asset) {
|
||||||
$this->authorize('delete', $asset);
|
$this->authorize('delete', $asset);
|
||||||
|
@ -59,6 +61,7 @@ class BulkAssetsController extends Controller
|
||||||
return view('hardware/bulk-delete')->with('assets', $assets);
|
return view('hardware/bulk-delete')->with('assets', $assets);
|
||||||
|
|
||||||
case 'restore':
|
case 'restore':
|
||||||
|
$this->authorize('update', Asset::class);
|
||||||
$assets = Asset::withTrashed()->find($asset_ids);
|
$assets = Asset::withTrashed()->find($asset_ids);
|
||||||
$assets->each(function ($asset) {
|
$assets->each(function ($asset) {
|
||||||
$this->authorize('delete', $asset);
|
$this->authorize('delete', $asset);
|
||||||
|
@ -67,6 +70,7 @@ class BulkAssetsController extends Controller
|
||||||
return view('hardware/bulk-restore')->with('assets', $assets);
|
return view('hardware/bulk-restore')->with('assets', $assets);
|
||||||
|
|
||||||
case 'edit':
|
case 'edit':
|
||||||
|
$this->authorize('update', Asset::class);
|
||||||
return view('hardware/bulk')
|
return view('hardware/bulk')
|
||||||
->with('assets', $asset_ids)
|
->with('assets', $asset_ids)
|
||||||
->with('statuslabel_list', Helper::statusLabelList());
|
->with('statuslabel_list', Helper::statusLabelList());
|
||||||
|
@ -145,7 +149,7 @@ class BulkAssetsController extends Controller
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($request->filled('purchase_cost')) {
|
if ($request->filled('purchase_cost')) {
|
||||||
$this->update_array['purchase_cost'] = Helper::ParseCurrency($request->input('purchase_cost'));
|
$this->update_array['purchase_cost'] = $request->input('purchase_cost');
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($request->filled('company_id')) {
|
if ($request->filled('company_id')) {
|
||||||
|
@ -333,6 +337,7 @@ class BulkAssetsController extends Controller
|
||||||
|
|
||||||
}
|
}
|
||||||
public function restore(Request $request) {
|
public function restore(Request $request) {
|
||||||
|
$this->authorize('update', Asset::class);
|
||||||
$assetIds = $request->get('ids');
|
$assetIds = $request->get('ids');
|
||||||
if (empty($assetIds)) {
|
if (empty($assetIds)) {
|
||||||
return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.restore.nothing_updated'));
|
return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.restore.nothing_updated'));
|
||||||
|
|
|
@ -78,7 +78,7 @@ class ComponentsController extends Controller
|
||||||
$component->min_amt = $request->input('min_amt', null);
|
$component->min_amt = $request->input('min_amt', null);
|
||||||
$component->serial = $request->input('serial', null);
|
$component->serial = $request->input('serial', null);
|
||||||
$component->purchase_date = $request->input('purchase_date', null);
|
$component->purchase_date = $request->input('purchase_date', null);
|
||||||
$component->purchase_cost = Helper::ParseCurrency($request->input('purchase_cost', null));
|
$component->purchase_cost = $request->input('purchase_cost', null);
|
||||||
$component->qty = $request->input('qty');
|
$component->qty = $request->input('qty');
|
||||||
$component->user_id = Auth::id();
|
$component->user_id = Auth::id();
|
||||||
$component->notes = $request->input('notes');
|
$component->notes = $request->input('notes');
|
||||||
|
@ -153,7 +153,7 @@ class ComponentsController extends Controller
|
||||||
$component->min_amt = $request->input('min_amt');
|
$component->min_amt = $request->input('min_amt');
|
||||||
$component->serial = $request->input('serial');
|
$component->serial = $request->input('serial');
|
||||||
$component->purchase_date = $request->input('purchase_date');
|
$component->purchase_date = $request->input('purchase_date');
|
||||||
$component->purchase_cost = Helper::ParseCurrency(request('purchase_cost'));
|
$component->purchase_cost = request('purchase_cost');
|
||||||
$component->qty = $request->input('qty');
|
$component->qty = $request->input('qty');
|
||||||
$component->notes = $request->input('notes');
|
$component->notes = $request->input('notes');
|
||||||
|
|
||||||
|
|
|
@ -77,7 +77,7 @@ class ConsumablesController extends Controller
|
||||||
$consumable->model_number = $request->input('model_number');
|
$consumable->model_number = $request->input('model_number');
|
||||||
$consumable->item_no = $request->input('item_no');
|
$consumable->item_no = $request->input('item_no');
|
||||||
$consumable->purchase_date = $request->input('purchase_date');
|
$consumable->purchase_date = $request->input('purchase_date');
|
||||||
$consumable->purchase_cost = Helper::ParseCurrency($request->input('purchase_cost'));
|
$consumable->purchase_cost = $request->input('purchase_cost');
|
||||||
$consumable->qty = $request->input('qty');
|
$consumable->qty = $request->input('qty');
|
||||||
$consumable->user_id = Auth::id();
|
$consumable->user_id = Auth::id();
|
||||||
$consumable->notes = $request->input('notes');
|
$consumable->notes = $request->input('notes');
|
||||||
|
@ -154,7 +154,7 @@ class ConsumablesController extends Controller
|
||||||
$consumable->model_number = $request->input('model_number');
|
$consumable->model_number = $request->input('model_number');
|
||||||
$consumable->item_no = $request->input('item_no');
|
$consumable->item_no = $request->input('item_no');
|
||||||
$consumable->purchase_date = $request->input('purchase_date');
|
$consumable->purchase_date = $request->input('purchase_date');
|
||||||
$consumable->purchase_cost = Helper::ParseCurrency($request->input('purchase_cost'));
|
$consumable->purchase_cost = $request->input('purchase_cost');
|
||||||
$consumable->qty = Helper::ParseFloat($request->input('qty'));
|
$consumable->qty = Helper::ParseFloat($request->input('qty'));
|
||||||
$consumable->notes = $request->input('notes');
|
$consumable->notes = $request->input('notes');
|
||||||
|
|
||||||
|
|
|
@ -112,4 +112,54 @@ class LicenseCheckinController extends Controller
|
||||||
// Redirect to the license page with error
|
// Redirect to the license page with error
|
||||||
return redirect()->route('licenses.index')->with('error', trans('admin/licenses/message.checkin.error'));
|
return redirect()->route('licenses.index')->with('error', trans('admin/licenses/message.checkin.error'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bulk checkin all license seats
|
||||||
|
*
|
||||||
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
|
* @see LicenseCheckinController::create() method that provides the form view
|
||||||
|
* @since [v6.1.1]
|
||||||
|
* @return \Illuminate\Http\RedirectResponse
|
||||||
|
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||||
|
*/
|
||||||
|
|
||||||
|
public function bulkCheckin(Request $request, $licenseId) {
|
||||||
|
|
||||||
|
$license = License::findOrFail($licenseId);
|
||||||
|
$this->authorize('checkin', $license);
|
||||||
|
|
||||||
|
$licenseSeatsByUser = LicenseSeat::where('license_id', '=', $licenseId)
|
||||||
|
->whereNotNull('assigned_to')
|
||||||
|
->with('user')
|
||||||
|
->get();
|
||||||
|
|
||||||
|
foreach ($licenseSeatsByUser as $user_seat) {
|
||||||
|
$user_seat->assigned_to = null;
|
||||||
|
|
||||||
|
if ($user_seat->save()) {
|
||||||
|
\Log::debug('Checking in '.$license->name.' from user '.$user_seat->username);
|
||||||
|
$user_seat->logCheckin($user_seat->user, trans('admin/licenses/general.bulk.checkin_all.log_msg'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$licenseSeatsByAsset = LicenseSeat::where('license_id', '=', $licenseId)
|
||||||
|
->whereNotNull('asset_id')
|
||||||
|
->with('asset')
|
||||||
|
->get();
|
||||||
|
|
||||||
|
$count = 0;
|
||||||
|
foreach ($licenseSeatsByAsset as $asset_seat) {
|
||||||
|
$asset_seat->asset_id = null;
|
||||||
|
|
||||||
|
if ($asset_seat->save()) {
|
||||||
|
\Log::debug('Checking in '.$license->name.' from asset '.$asset_seat->asset_tag);
|
||||||
|
$asset_seat->logCheckin($asset_seat->asset, trans('admin/licenses/general.bulk.checkin_all.log_msg'));
|
||||||
|
$count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return redirect()->back()->with('success', trans_choice('admin/licenses/general.bulk.checkin_all.success', 2, ['count' => $count] ));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -126,4 +126,70 @@ class LicenseCheckoutController extends Controller
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bulk checkin all license seats
|
||||||
|
*
|
||||||
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
|
* @see LicenseCheckinController::create() method that provides the form view
|
||||||
|
* @since [v6.1.1]
|
||||||
|
* @return \Illuminate\Http\RedirectResponse
|
||||||
|
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||||
|
*/
|
||||||
|
|
||||||
|
public function bulkCheckout($licenseId) {
|
||||||
|
|
||||||
|
\Log::debug('Checking out '.$licenseId.' via bulk');
|
||||||
|
$license = License::findOrFail($licenseId);
|
||||||
|
$this->authorize('checkin', $license);
|
||||||
|
$avail_count = $license->getAvailSeatsCountAttribute();
|
||||||
|
|
||||||
|
$users = User::whereNull('deleted_at')->where('autoassign_licenses', '=', 1)->with('licenses')->get();
|
||||||
|
\Log::debug($avail_count.' will be assigned');
|
||||||
|
|
||||||
|
if ($users->count() > $avail_count) {
|
||||||
|
\Log::debug('You do not have enough free seats to complete this task, so we will check out as many as we can. ');
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the license is valid, check that there is an available seat
|
||||||
|
if ($license->availCount()->count() < 1) {
|
||||||
|
return redirect()->back()->with('error', trans('admin/licenses/general.bulk.checkout_all.error_no_seats'));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$assigned_count = 0;
|
||||||
|
|
||||||
|
foreach ($users as $user) {
|
||||||
|
|
||||||
|
// Check to make sure this user doesn't already have this license checked out to them
|
||||||
|
if ($user->licenses->where('id', '=', $licenseId)->count()) {
|
||||||
|
\Log::debug($user->username.' already has this license checked out to them. Skipping... ');
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$licenseSeat = $license->freeSeat();
|
||||||
|
|
||||||
|
// Update the seat with checkout info
|
||||||
|
$licenseSeat->assigned_to = $user->id;
|
||||||
|
|
||||||
|
if ($licenseSeat->save()) {
|
||||||
|
$avail_count--;
|
||||||
|
$assigned_count++;
|
||||||
|
$licenseSeat->logCheckout(trans('admin/licenses/general.bulk.checkout_all.log_msg'), $user);
|
||||||
|
\Log::debug('License '.$license->name.' seat '.$licenseSeat->id.' checked out to '.$user->username);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($avail_count == 0) {
|
||||||
|
return redirect()->back()->with('warning', trans('admin/licenses/general.bulk.checkout_all.warn_not_enough_seats', ['count' => $assigned_count]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($assigned_count == 0) {
|
||||||
|
return redirect()->back()->with('warning', trans('admin/licenses/general.bulk.checkout_all.warn_no_avail_users', ['count' => $assigned_count]));
|
||||||
|
}
|
||||||
|
|
||||||
|
return redirect()->back()->with('success', trans_choice('admin/licenses/general.bulk.checkout_all.success', 2, ['count' => $assigned_count] ));
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,8 @@ use App\Helpers\Helper;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Models\Company;
|
use App\Models\Company;
|
||||||
use App\Models\License;
|
use App\Models\License;
|
||||||
|
use App\Models\LicenseSeat;
|
||||||
|
use App\Models\User;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
|
@ -86,7 +88,7 @@ class LicensesController extends Controller
|
||||||
$license->name = $request->input('name');
|
$license->name = $request->input('name');
|
||||||
$license->notes = $request->input('notes');
|
$license->notes = $request->input('notes');
|
||||||
$license->order_number = $request->input('order_number');
|
$license->order_number = $request->input('order_number');
|
||||||
$license->purchase_cost = Helper::ParseCurrency($request->input('purchase_cost'));
|
$license->purchase_cost = $request->input('purchase_cost');
|
||||||
$license->purchase_date = $request->input('purchase_date');
|
$license->purchase_date = $request->input('purchase_date');
|
||||||
$license->purchase_order = $request->input('purchase_order');
|
$license->purchase_order = $request->input('purchase_order');
|
||||||
$license->purchase_order = $request->input('purchase_order');
|
$license->purchase_order = $request->input('purchase_order');
|
||||||
|
@ -164,7 +166,7 @@ class LicensesController extends Controller
|
||||||
$license->name = $request->input('name');
|
$license->name = $request->input('name');
|
||||||
$license->notes = $request->input('notes');
|
$license->notes = $request->input('notes');
|
||||||
$license->order_number = $request->input('order_number');
|
$license->order_number = $request->input('order_number');
|
||||||
$license->purchase_cost = Helper::ParseCurrency($request->input('purchase_cost'));
|
$license->purchase_cost = $request->input('purchase_cost');
|
||||||
$license->purchase_date = $request->input('purchase_date');
|
$license->purchase_date = $request->input('purchase_date');
|
||||||
$license->purchase_order = $request->input('purchase_order');
|
$license->purchase_order = $request->input('purchase_order');
|
||||||
$license->reassignable = $request->input('reassignable', 0);
|
$license->reassignable = $request->input('reassignable', 0);
|
||||||
|
@ -233,16 +235,40 @@ class LicensesController extends Controller
|
||||||
{
|
{
|
||||||
$license = License::with('assignedusers')->find($licenseId);
|
$license = License::with('assignedusers')->find($licenseId);
|
||||||
|
|
||||||
if ($license) {
|
if (!$license) {
|
||||||
$this->authorize('view', $license);
|
return redirect()->route('licenses.index')
|
||||||
|
->with('error', trans('admin/licenses/message.does_not_exist'));
|
||||||
return view('licenses/view', compact('license'));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return redirect()->route('licenses.index')
|
$users_count = User::where('autoassign_licenses', '1')->count();
|
||||||
->with('error', trans('admin/licenses/message.does_not_exist'));
|
$total_seats_count = $license->totalSeatsByLicenseID();
|
||||||
|
$available_seats_count = $license->availCount()->count();
|
||||||
|
$checkedout_seats_count = ($total_seats_count - $available_seats_count);
|
||||||
|
|
||||||
|
\Log::debug('Total: '.$total_seats_count);
|
||||||
|
\Log::debug('Users: '.$users_count);
|
||||||
|
\Log::debug('Available: '.$available_seats_count);
|
||||||
|
\Log::debug('Checkedout: '.$checkedout_seats_count);
|
||||||
|
|
||||||
|
|
||||||
|
$this->authorize('view', $license);
|
||||||
|
return view('licenses.view', compact('license'))
|
||||||
|
->with('users_count', $users_count)
|
||||||
|
->with('total_seats_count', $total_seats_count)
|
||||||
|
->with('available_seats_count', $available_seats_count)
|
||||||
|
->with('checkedout_seats_count', $checkedout_seats_count);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a view with prepopulated data for clone
|
||||||
|
*
|
||||||
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
|
* @param int $licenseId
|
||||||
|
* @return \Illuminate\Http\RedirectResponse
|
||||||
|
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||||
|
*/
|
||||||
public function getClone($licenseId = null)
|
public function getClone($licenseId = null)
|
||||||
{
|
{
|
||||||
if (is_null($license_to_clone = License::find($licenseId))) {
|
if (is_null($license_to_clone = License::find($licenseId))) {
|
||||||
|
|
|
@ -68,6 +68,7 @@ class ManufacturersController extends Controller
|
||||||
$manufacturer->user_id = Auth::id();
|
$manufacturer->user_id = Auth::id();
|
||||||
$manufacturer->url = $request->input('url');
|
$manufacturer->url = $request->input('url');
|
||||||
$manufacturer->support_url = $request->input('support_url');
|
$manufacturer->support_url = $request->input('support_url');
|
||||||
|
$manufacturer->warranty_lookup_url = $request->input('warranty_lookup_url');
|
||||||
$manufacturer->support_phone = $request->input('support_phone');
|
$manufacturer->support_phone = $request->input('support_phone');
|
||||||
$manufacturer->support_email = $request->input('support_email');
|
$manufacturer->support_email = $request->input('support_email');
|
||||||
$manufacturer = $request->handleImages($manufacturer);
|
$manufacturer = $request->handleImages($manufacturer);
|
||||||
|
@ -123,10 +124,11 @@ class ManufacturersController extends Controller
|
||||||
return redirect()->route('manufacturers.index')->with('error', trans('admin/manufacturers/message.does_not_exist'));
|
return redirect()->route('manufacturers.index')->with('error', trans('admin/manufacturers/message.does_not_exist'));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save the data
|
// Save the data
|
||||||
$manufacturer->name = $request->input('name');
|
$manufacturer->name = $request->input('name');
|
||||||
$manufacturer->url = $request->input('url');
|
$manufacturer->url = $request->input('url');
|
||||||
$manufacturer->support_url = $request->input('support_url');
|
$manufacturer->support_url = $request->input('support_url');
|
||||||
|
$manufacturer->warranty_lookup_url = $request->input('warranty_lookup_url');
|
||||||
$manufacturer->support_phone = $request->input('support_phone');
|
$manufacturer->support_phone = $request->input('support_phone');
|
||||||
$manufacturer->support_email = $request->input('support_email');
|
$manufacturer->support_email = $request->input('support_email');
|
||||||
|
|
||||||
|
|
|
@ -961,6 +961,7 @@ class SettingsController extends Controller
|
||||||
$setting->ldap_phone_field = $request->input('ldap_phone');
|
$setting->ldap_phone_field = $request->input('ldap_phone');
|
||||||
$setting->ldap_jobtitle = $request->input('ldap_jobtitle');
|
$setting->ldap_jobtitle = $request->input('ldap_jobtitle');
|
||||||
$setting->ldap_country = $request->input('ldap_country');
|
$setting->ldap_country = $request->input('ldap_country');
|
||||||
|
$setting->ldap_location = $request->input('ldap_location');
|
||||||
$setting->ldap_dept = $request->input('ldap_dept');
|
$setting->ldap_dept = $request->input('ldap_dept');
|
||||||
$setting->ldap_client_tls_cert = $request->input('ldap_client_tls_cert');
|
$setting->ldap_client_tls_cert = $request->input('ldap_client_tls_cert');
|
||||||
$setting->ldap_client_tls_key = $request->input('ldap_client_tls_key');
|
$setting->ldap_client_tls_key = $request->input('ldap_client_tls_key');
|
||||||
|
|
|
@ -113,7 +113,8 @@ class BulkUsersController extends Controller
|
||||||
->conditionallyAddItem('locale')
|
->conditionallyAddItem('locale')
|
||||||
->conditionallyAddItem('remote')
|
->conditionallyAddItem('remote')
|
||||||
->conditionallyAddItem('ldap_import')
|
->conditionallyAddItem('ldap_import')
|
||||||
->conditionallyAddItem('activated');
|
->conditionallyAddItem('activated')
|
||||||
|
->conditionallyAddItem('autoassign_licenses');
|
||||||
|
|
||||||
|
|
||||||
// If the manager_id is one of the users being updated, generate a warning.
|
// If the manager_id is one of the users being updated, generate a warning.
|
||||||
|
|
|
@ -120,7 +120,7 @@ class UsersController extends Controller
|
||||||
$user->created_by = Auth::user()->id;
|
$user->created_by = Auth::user()->id;
|
||||||
$user->start_date = $request->input('start_date', null);
|
$user->start_date = $request->input('start_date', null);
|
||||||
$user->end_date = $request->input('end_date', null);
|
$user->end_date = $request->input('end_date', null);
|
||||||
$user->autoassign_licenses= $request->input('autoassign_licenses', 1);
|
$user->autoassign_licenses = $request->input('autoassign_licenses', 0);
|
||||||
|
|
||||||
// Strip out the superuser permission if the user isn't a superadmin
|
// Strip out the superuser permission if the user isn't a superadmin
|
||||||
$permissions_array = $request->input('permission');
|
$permissions_array = $request->input('permission');
|
||||||
|
@ -210,7 +210,6 @@ class UsersController extends Controller
|
||||||
*/
|
*/
|
||||||
public function update(SaveUserRequest $request, $id = null)
|
public function update(SaveUserRequest $request, $id = null)
|
||||||
{
|
{
|
||||||
|
|
||||||
// We need to reverse the UI specific logic for our
|
// We need to reverse the UI specific logic for our
|
||||||
// permissions here before we update the user.
|
// permissions here before we update the user.
|
||||||
$permissions = $request->input('permissions', []);
|
$permissions = $request->input('permissions', []);
|
||||||
|
@ -268,14 +267,15 @@ class UsersController extends Controller
|
||||||
$user->city = $request->input('city', null);
|
$user->city = $request->input('city', null);
|
||||||
$user->state = $request->input('state', null);
|
$user->state = $request->input('state', null);
|
||||||
$user->country = $request->input('country', null);
|
$user->country = $request->input('country', null);
|
||||||
$user->activated = $request->input('activated', 0);
|
// if a user is editing themselves we should always keep activated true
|
||||||
|
$user->activated = $request->input('activated', $request->user()->is($user) ? 1 : 0);
|
||||||
$user->zip = $request->input('zip', null);
|
$user->zip = $request->input('zip', null);
|
||||||
$user->remote = $request->input('remote', 0);
|
$user->remote = $request->input('remote', 0);
|
||||||
$user->vip = $request->input('vip', 0);
|
$user->vip = $request->input('vip', 0);
|
||||||
$user->website = $request->input('website', null);
|
$user->website = $request->input('website', null);
|
||||||
$user->start_date = $request->input('start_date', null);
|
$user->start_date = $request->input('start_date', null);
|
||||||
$user->end_date = $request->input('end_date', null);
|
$user->end_date = $request->input('end_date', null);
|
||||||
$user->autoassign_licenses = $request->input('autoassign_licenses', 1);
|
$user->autoassign_licenses = $request->input('autoassign_licenses', 0);
|
||||||
|
|
||||||
// Update the location of any assets checked out to this user
|
// Update the location of any assets checked out to this user
|
||||||
Asset::where('assigned_type', User::class)
|
Asset::where('assigned_type', User::class)
|
||||||
|
|
|
@ -56,7 +56,7 @@ class LicensesTransformer
|
||||||
'checkin' => Gate::allows('checkin', License::class),
|
'checkin' => Gate::allows('checkin', License::class),
|
||||||
'clone' => Gate::allows('create', License::class),
|
'clone' => Gate::allows('create', License::class),
|
||||||
'update' => Gate::allows('update', License::class),
|
'update' => Gate::allows('update', License::class),
|
||||||
'delete' => Gate::allows('delete', License::class),
|
'delete' => (Gate::allows('delete', License::class) && ($license->seats == $license->availCount()->count())) ? true : false,
|
||||||
];
|
];
|
||||||
|
|
||||||
$array += $permissions_array;
|
$array += $permissions_array;
|
||||||
|
|
|
@ -29,6 +29,7 @@ class ManufacturersTransformer
|
||||||
'url' => e($manufacturer->url),
|
'url' => e($manufacturer->url),
|
||||||
'image' => ($manufacturer->image) ? Storage::disk('public')->url('manufacturers/'.e($manufacturer->image)) : null,
|
'image' => ($manufacturer->image) ? Storage::disk('public')->url('manufacturers/'.e($manufacturer->image)) : null,
|
||||||
'support_url' => e($manufacturer->support_url),
|
'support_url' => e($manufacturer->support_url),
|
||||||
|
'warranty_lookup_url' => e($manufacturer->warranty_lookup_url),
|
||||||
'support_phone' => e($manufacturer->support_phone),
|
'support_phone' => e($manufacturer->support_phone),
|
||||||
'support_email' => e($manufacturer->support_email),
|
'support_email' => e($manufacturer->support_email),
|
||||||
'assets_count' => (int) $manufacturer->assets_count,
|
'assets_count' => (int) $manufacturer->assets_count,
|
||||||
|
|
|
@ -56,6 +56,7 @@ class UsersTransformer
|
||||||
'notes'=> e($user->notes),
|
'notes'=> e($user->notes),
|
||||||
'permissions' => $user->decodePermissions(),
|
'permissions' => $user->decodePermissions(),
|
||||||
'activated' => ($user->activated == '1') ? true : false,
|
'activated' => ($user->activated == '1') ? true : false,
|
||||||
|
'autoassign_licenses' => ($user->autoassign_licenses == '1') ? true : false,
|
||||||
'ldap_import' => ($user->ldap_import == '1') ? true : false,
|
'ldap_import' => ($user->ldap_import == '1') ? true : false,
|
||||||
'two_factor_enrolled' => ($user->two_factor_active_and_enrolled()) ? true : false,
|
'two_factor_enrolled' => ($user->two_factor_active_and_enrolled()) ? true : false,
|
||||||
'two_factor_optin' => ($user->two_factor_active()) ? true : false,
|
'two_factor_optin' => ($user->two_factor_active()) ? true : false,
|
||||||
|
|
|
@ -58,7 +58,8 @@ class UserImporter extends ItemImporter
|
||||||
$this->item['department_id'] = $this->createOrFetchDepartment($this->findCsvMatch($row, 'department'));
|
$this->item['department_id'] = $this->createOrFetchDepartment($this->findCsvMatch($row, 'department'));
|
||||||
$this->item['manager_id'] = $this->fetchManager($this->findCsvMatch($row, 'manager_first_name'), $this->findCsvMatch($row, 'manager_last_name'));
|
$this->item['manager_id'] = $this->fetchManager($this->findCsvMatch($row, 'manager_first_name'), $this->findCsvMatch($row, 'manager_last_name'));
|
||||||
$this->item['remote'] =($this->fetchHumanBoolean($this->findCsvMatch($row, 'remote')) ==1 ) ? '1' : 0;
|
$this->item['remote'] =($this->fetchHumanBoolean($this->findCsvMatch($row, 'remote')) ==1 ) ? '1' : 0;
|
||||||
$this->item['vip'] =($this->fetchHumanBoolean($this->findCsvMatch($row, 'vip')) ==1 ) ? '1' : 0;
|
$this->item['vip'] = ($this->fetchHumanBoolean($this->findCsvMatch($row, 'vip')) ==1 ) ? '1' : 0;
|
||||||
|
$this->item['autoassign_licenses'] = ($this->fetchHumanBoolean($this->findCsvMatch($row, 'autoassign_licenses')) ==1 ) ? '1' : 0;
|
||||||
|
|
||||||
|
|
||||||
$user_department = $this->findCsvMatch($row, 'department');
|
$user_department = $this->findCsvMatch($row, 'department');
|
||||||
|
|
|
@ -2,22 +2,21 @@
|
||||||
|
|
||||||
namespace App\Listeners;
|
namespace App\Listeners;
|
||||||
|
|
||||||
|
use App\Events\CheckoutableCheckedOut;
|
||||||
use App\Models\Accessory;
|
use App\Models\Accessory;
|
||||||
use App\Models\Asset;
|
use App\Models\Asset;
|
||||||
use App\Models\CheckoutAcceptance;
|
use App\Models\CheckoutAcceptance;
|
||||||
|
use App\Models\Component;
|
||||||
use App\Models\Consumable;
|
use App\Models\Consumable;
|
||||||
use App\Models\LicenseSeat;
|
use App\Models\LicenseSeat;
|
||||||
use App\Models\Recipients\AdminRecipient;
|
use App\Models\Recipients\AdminRecipient;
|
||||||
use App\Models\Setting;
|
use App\Models\Setting;
|
||||||
use App\Models\User;
|
|
||||||
use App\Notifications\CheckinAccessoryNotification;
|
use App\Notifications\CheckinAccessoryNotification;
|
||||||
use App\Notifications\CheckinAssetNotification;
|
use App\Notifications\CheckinAssetNotification;
|
||||||
use App\Notifications\CheckinLicenseNotification;
|
|
||||||
use App\Notifications\CheckinLicenseSeatNotification;
|
use App\Notifications\CheckinLicenseSeatNotification;
|
||||||
use App\Notifications\CheckoutAccessoryNotification;
|
use App\Notifications\CheckoutAccessoryNotification;
|
||||||
use App\Notifications\CheckoutAssetNotification;
|
use App\Notifications\CheckoutAssetNotification;
|
||||||
use App\Notifications\CheckoutConsumableNotification;
|
use App\Notifications\CheckoutConsumableNotification;
|
||||||
use App\Notifications\CheckoutLicenseNotification;
|
|
||||||
use App\Notifications\CheckoutLicenseSeatNotification;
|
use App\Notifications\CheckoutLicenseSeatNotification;
|
||||||
use Illuminate\Support\Facades\Notification;
|
use Illuminate\Support\Facades\Notification;
|
||||||
use Exception;
|
use Exception;
|
||||||
|
@ -25,18 +24,17 @@ use Log;
|
||||||
|
|
||||||
class CheckoutableListener
|
class CheckoutableListener
|
||||||
{
|
{
|
||||||
|
private array $skipNotificationsFor = [
|
||||||
|
Component::class,
|
||||||
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notify the user about the checked out checkoutable and add a record to the
|
* Notify the user and post to webhook about the checked out checkoutable
|
||||||
* checkout_requests table.
|
* and add a record to the checkout_requests table.
|
||||||
*/
|
*/
|
||||||
public function onCheckedOut($event)
|
public function onCheckedOut($event)
|
||||||
{
|
{
|
||||||
|
if ($this->shouldNotSendAnyNotifications($event->checkoutable)){
|
||||||
|
|
||||||
/**
|
|
||||||
* When the item wasn't checked out to a user, we can't send notifications
|
|
||||||
*/
|
|
||||||
if (! $event->checkedOutTo instanceof User) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,6 +44,11 @@ class CheckoutableListener
|
||||||
$acceptance = $this->getCheckoutAcceptance($event);
|
$acceptance = $this->getCheckoutAcceptance($event);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
if ($this->shouldSendWebhookNotification()) {
|
||||||
|
Notification::route('slack', Setting::getSettings()->webhook_endpoint)
|
||||||
|
->notify($this->getCheckoutNotification($event));
|
||||||
|
}
|
||||||
|
|
||||||
if (! $event->checkedOutTo->locale) {
|
if (! $event->checkedOutTo->locale) {
|
||||||
Notification::locale(Setting::getSettings()->locale)->send(
|
Notification::locale(Setting::getSettings()->locale)->send(
|
||||||
$this->getNotifiables($event),
|
$this->getNotifiables($event),
|
||||||
|
@ -63,16 +66,13 @@ class CheckoutableListener
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notify the user about the checked in checkoutable
|
* Notify the user and post to webhook about the checked in checkoutable
|
||||||
*/
|
*/
|
||||||
public function onCheckedIn($event)
|
public function onCheckedIn($event)
|
||||||
{
|
{
|
||||||
\Log::debug('onCheckedIn in the Checkoutable listener fired');
|
\Log::debug('onCheckedIn in the Checkoutable listener fired');
|
||||||
|
|
||||||
/**
|
if ($this->shouldNotSendAnyNotifications($event->checkoutable)) {
|
||||||
* When the item wasn't checked out to a user, we can't send notifications
|
|
||||||
*/
|
|
||||||
if (! $event->checkedOutTo instanceof User) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,6 +90,11 @@ class CheckoutableListener
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
if ($this->shouldSendWebhookNotification()) {
|
||||||
|
Notification::route('slack', Setting::getSettings()->webhook_endpoint)
|
||||||
|
->notify($this->getCheckinNotification($event));
|
||||||
|
}
|
||||||
|
|
||||||
// Use default locale
|
// Use default locale
|
||||||
if (! $event->checkedOutTo->locale) {
|
if (! $event->checkedOutTo->locale) {
|
||||||
Notification::locale(Setting::getSettings()->locale)->send(
|
Notification::locale(Setting::getSettings()->locale)->send(
|
||||||
|
@ -182,11 +187,11 @@ class CheckoutableListener
|
||||||
/**
|
/**
|
||||||
* Get the appropriate notification for the event
|
* Get the appropriate notification for the event
|
||||||
*
|
*
|
||||||
* @param CheckoutableCheckedIn $event
|
* @param CheckoutableCheckedOut $event
|
||||||
* @param CheckoutAcceptance $acceptance
|
* @param CheckoutAcceptance|null $acceptance
|
||||||
* @return Notification
|
* @return Notification
|
||||||
*/
|
*/
|
||||||
private function getCheckoutNotification($event, $acceptance)
|
private function getCheckoutNotification($event, $acceptance = null)
|
||||||
{
|
{
|
||||||
$notificationClass = null;
|
$notificationClass = null;
|
||||||
|
|
||||||
|
@ -225,4 +230,14 @@ class CheckoutableListener
|
||||||
'App\Listeners\CheckoutableListener@onCheckedOut'
|
'App\Listeners\CheckoutableListener@onCheckedOut'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function shouldNotSendAnyNotifications($checkoutable): bool
|
||||||
|
{
|
||||||
|
return in_array(get_class($checkoutable), $this->skipNotificationsFor);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function shouldSendWebhookNotification(): bool
|
||||||
|
{
|
||||||
|
return Setting::getSettings() && Setting::getSettings()->webhook_endpoint;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,8 +95,8 @@ class AssetMaintenance extends Model implements ICompanyableChild
|
||||||
*/
|
*/
|
||||||
public function setCostAttribute($value)
|
public function setCostAttribute($value)
|
||||||
{
|
{
|
||||||
$value = Helper::ParseFloat($value);
|
$value = Helper::ParseCurrency($value);
|
||||||
if ($value == '0.0') {
|
if ($value == 0) {
|
||||||
$value = null;
|
$value = null;
|
||||||
}
|
}
|
||||||
$this->attributes['cost'] = $value;
|
$this->attributes['cost'] = $value;
|
||||||
|
|
|
@ -213,6 +213,7 @@ class Ldap extends Model
|
||||||
$ldap_result_phone = Setting::getSettings()->ldap_phone;
|
$ldap_result_phone = Setting::getSettings()->ldap_phone;
|
||||||
$ldap_result_jobtitle = Setting::getSettings()->ldap_jobtitle;
|
$ldap_result_jobtitle = Setting::getSettings()->ldap_jobtitle;
|
||||||
$ldap_result_country = Setting::getSettings()->ldap_country;
|
$ldap_result_country = Setting::getSettings()->ldap_country;
|
||||||
|
$ldap_result_location = Setting::getSettings()->ldap_location;
|
||||||
$ldap_result_dept = Setting::getSettings()->ldap_dept;
|
$ldap_result_dept = Setting::getSettings()->ldap_dept;
|
||||||
$ldap_result_manager = Setting::getSettings()->ldap_manager;
|
$ldap_result_manager = Setting::getSettings()->ldap_manager;
|
||||||
// Get LDAP user data
|
// Get LDAP user data
|
||||||
|
@ -227,6 +228,7 @@ class Ldap extends Model
|
||||||
$item['country'] = $ldapattributes[$ldap_result_country][0] ?? '';
|
$item['country'] = $ldapattributes[$ldap_result_country][0] ?? '';
|
||||||
$item['department'] = $ldapattributes[$ldap_result_dept][0] ?? '';
|
$item['department'] = $ldapattributes[$ldap_result_dept][0] ?? '';
|
||||||
$item['manager'] = $ldapattributes[$ldap_result_manager][0] ?? '';
|
$item['manager'] = $ldapattributes[$ldap_result_manager][0] ?? '';
|
||||||
|
$item['location'] = $ldapattributes[$ldap_result_location][0] ?? '';
|
||||||
|
|
||||||
return $item;
|
return $item;
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,10 +106,10 @@ class License extends Depreciable
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $searchableRelations = [
|
protected $searchableRelations = [
|
||||||
'manufacturer' => ['name'],
|
'manufacturer' => ['name'],
|
||||||
'company' => ['name'],
|
'company' => ['name'],
|
||||||
'category' => ['name'],
|
'category' => ['name'],
|
||||||
'depreciation' => ['name'],
|
'depreciation' => ['name'],
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -425,7 +425,7 @@ class License extends Depreciable
|
||||||
public static function assetcount()
|
public static function assetcount()
|
||||||
{
|
{
|
||||||
return LicenseSeat::whereNull('deleted_at')
|
return LicenseSeat::whereNull('deleted_at')
|
||||||
->count();
|
->count();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -441,8 +441,8 @@ class License extends Depreciable
|
||||||
public function totalSeatsByLicenseID()
|
public function totalSeatsByLicenseID()
|
||||||
{
|
{
|
||||||
return LicenseSeat::where('license_id', '=', $this->id)
|
return LicenseSeat::where('license_id', '=', $this->id)
|
||||||
->whereNull('deleted_at')
|
->whereNull('deleted_at')
|
||||||
->count();
|
->count();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -486,11 +486,12 @@ class License extends Depreciable
|
||||||
public static function availassetcount()
|
public static function availassetcount()
|
||||||
{
|
{
|
||||||
return LicenseSeat::whereNull('assigned_to')
|
return LicenseSeat::whereNull('assigned_to')
|
||||||
->whereNull('asset_id')
|
->whereNull('asset_id')
|
||||||
->whereNull('deleted_at')
|
->whereNull('deleted_at')
|
||||||
->count();
|
->count();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the number of total available seats for this license
|
* Returns the number of total available seats for this license
|
||||||
*
|
*
|
||||||
|
@ -533,7 +534,7 @@ class License extends Depreciable
|
||||||
{
|
{
|
||||||
return $this->licenseSeatsRelation()->where(function ($query) {
|
return $this->licenseSeatsRelation()->where(function ($query) {
|
||||||
$query->whereNotNull('assigned_to')
|
$query->whereNotNull('assigned_to')
|
||||||
->orWhereNotNull('asset_id');
|
->orWhereNotNull('asset_id');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -621,13 +622,13 @@ class License extends Depreciable
|
||||||
public function freeSeat()
|
public function freeSeat()
|
||||||
{
|
{
|
||||||
return $this->licenseseats()
|
return $this->licenseseats()
|
||||||
->whereNull('deleted_at')
|
->whereNull('deleted_at')
|
||||||
->where(function ($query) {
|
->where(function ($query) {
|
||||||
$query->whereNull('assigned_to')
|
$query->whereNull('assigned_to')
|
||||||
->whereNull('asset_id');
|
->whereNull('asset_id');
|
||||||
})
|
})
|
||||||
->orderBy('id', 'asc')
|
->orderBy('id', 'asc')
|
||||||
->first();
|
->first();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -657,11 +658,11 @@ class License extends Depreciable
|
||||||
$days = (is_null($days)) ? 60 : $days;
|
$days = (is_null($days)) ? 60 : $days;
|
||||||
|
|
||||||
return self::whereNotNull('expiration_date')
|
return self::whereNotNull('expiration_date')
|
||||||
->whereNull('deleted_at')
|
->whereNull('deleted_at')
|
||||||
->whereRaw(DB::raw('DATE_SUB(`expiration_date`,INTERVAL '.$days.' DAY) <= DATE(NOW()) '))
|
->whereRaw(DB::raw('DATE_SUB(`expiration_date`,INTERVAL '.$days.' DAY) <= DATE(NOW()) '))
|
||||||
->where('expiration_date', '>', date('Y-m-d'))
|
->where('expiration_date', '>', date('Y-m-d'))
|
||||||
->orderBy('expiration_date', 'ASC')
|
->orderBy('expiration_date', 'ASC')
|
||||||
->get();
|
->get();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -6,13 +6,15 @@ use App\Models\Traits\Acceptable;
|
||||||
use App\Notifications\CheckinLicenseNotification;
|
use App\Notifications\CheckinLicenseNotification;
|
||||||
use App\Notifications\CheckoutLicenseNotification;
|
use App\Notifications\CheckoutLicenseNotification;
|
||||||
use App\Presenters\Presentable;
|
use App\Presenters\Presentable;
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
|
||||||
class LicenseSeat extends SnipeModel implements ICompanyableChild
|
class LicenseSeat extends SnipeModel implements ICompanyableChild
|
||||||
{
|
{
|
||||||
use CompanyableChildTrait;
|
use CompanyableChildTrait;
|
||||||
use SoftDeletes;
|
use HasFactory;
|
||||||
use Loggable;
|
use Loggable;
|
||||||
|
use SoftDeletes;
|
||||||
|
|
||||||
protected $presenter = \App\Presenters\LicenseSeatPresenter::class;
|
protected $presenter = \App\Presenters\LicenseSeatPresenter::class;
|
||||||
use Presentable;
|
use Presentable;
|
||||||
|
|
|
@ -23,8 +23,9 @@ class Manufacturer extends SnipeModel
|
||||||
protected $rules = [
|
protected $rules = [
|
||||||
'name' => 'required|min:2|max:255|unique:manufacturers,name,NULL,id,deleted_at,NULL',
|
'name' => 'required|min:2|max:255|unique:manufacturers,name,NULL,id,deleted_at,NULL',
|
||||||
'url' => 'url|nullable',
|
'url' => 'url|nullable',
|
||||||
'support_url' => 'url|nullable',
|
|
||||||
'support_email' => 'email|nullable',
|
'support_email' => 'email|nullable',
|
||||||
|
'support_url' => 'nullable|url',
|
||||||
|
'warranty_lookup_url' => 'starts_with:http://,https://,afp://,facetime://,file://,irc://','nullable'
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $hidden = ['user_id'];
|
protected $hidden = ['user_id'];
|
||||||
|
@ -51,6 +52,7 @@ class Manufacturer extends SnipeModel
|
||||||
'support_phone',
|
'support_phone',
|
||||||
'support_url',
|
'support_url',
|
||||||
'url',
|
'url',
|
||||||
|
'warranty_lookup_url',
|
||||||
];
|
];
|
||||||
|
|
||||||
use Searchable;
|
use Searchable;
|
||||||
|
|
|
@ -341,7 +341,15 @@ class Setting extends Model
|
||||||
'ad_domain',
|
'ad_domain',
|
||||||
'ad_append_domain',
|
'ad_append_domain',
|
||||||
'ldap_client_tls_key',
|
'ldap_client_tls_key',
|
||||||
'ldap_client_tls_cert'
|
'ldap_client_tls_cert',
|
||||||
|
'ldap_default_group',
|
||||||
|
'ldap_dept',
|
||||||
|
'ldap_emp_num',
|
||||||
|
'ldap_phone_field',
|
||||||
|
'ldap_jobtitle',
|
||||||
|
'ldap_manager',
|
||||||
|
'ldap_country',
|
||||||
|
'ldap_location',
|
||||||
])->first()->getAttributes();
|
])->first()->getAttributes();
|
||||||
|
|
||||||
return collect($ldapSettings);
|
return collect($ldapSettings);
|
||||||
|
|
|
@ -21,9 +21,9 @@ class SnipeModel extends Model
|
||||||
*/
|
*/
|
||||||
public function setPurchaseCostAttribute($value)
|
public function setPurchaseCostAttribute($value)
|
||||||
{
|
{
|
||||||
$value = Helper::ParseFloat($value);
|
$value = Helper::ParseCurrency($value);
|
||||||
|
|
||||||
if ($value == '0.0') {
|
if ($value == 0) {
|
||||||
$value = null;
|
$value = null;
|
||||||
}
|
}
|
||||||
$this->attributes['purchase_cost'] = $value;
|
$this->attributes['purchase_cost'] = $value;
|
||||||
|
|
|
@ -70,7 +70,11 @@ class SnipeSCIMConfig extends \ArieTimmerman\Laravel\SCIMServer\SCIMConfig
|
||||||
// Map a SCIM attribute to an attribute of the object.
|
// Map a SCIM attribute to an attribute of the object.
|
||||||
'mapping' => [
|
'mapping' => [
|
||||||
|
|
||||||
'id' => AttributeMapping::eloquent("id")->disableWrite(),
|
'id' => (new AttributeMapping())->setRead(
|
||||||
|
function (&$object) {
|
||||||
|
return (string)$object->id;
|
||||||
|
}
|
||||||
|
)->disableWrite(),
|
||||||
|
|
||||||
'externalId' => AttributeMapping::eloquent('scim_externalid'), // FIXME - I have a PR that changes a lot of this.
|
'externalId' => AttributeMapping::eloquent('scim_externalid'), // FIXME - I have a PR that changes a lot of this.
|
||||||
|
|
||||||
|
@ -174,7 +178,6 @@ class SnipeSCIMConfig extends \ArieTimmerman\Laravel\SCIMServer\SCIMConfig
|
||||||
'$ref' => null,
|
'$ref' => null,
|
||||||
'display' => null,
|
'display' => null,
|
||||||
'type' => null,
|
'type' => null,
|
||||||
'type' => null
|
|
||||||
]],
|
]],
|
||||||
|
|
||||||
'entitlements' => null,
|
'entitlements' => null,
|
||||||
|
|
|
@ -79,23 +79,6 @@ class Supplier extends SnipeModel
|
||||||
return $this->hasMany(Asset::class)->whereNull('deleted_at')->selectRaw('supplier_id, count(*) as count')->groupBy('supplier_id');
|
return $this->hasMany(Asset::class)->whereNull('deleted_at')->selectRaw('supplier_id, count(*) as count')->groupBy('supplier_id');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the license seat count attribute
|
|
||||||
*
|
|
||||||
* @todo I don't see the licenseSeatsRelation here?
|
|
||||||
*
|
|
||||||
* @author A. Gianotto <snipe@snipe.net>
|
|
||||||
* @since [v1.0]
|
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
|
||||||
*/
|
|
||||||
public function getLicenseSeatsCountAttribute()
|
|
||||||
{
|
|
||||||
if ($this->licenseSeatsRelation->first()) {
|
|
||||||
return $this->licenseSeatsRelation->first()->count;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Establishes the supplier -> assets relationship
|
* Establishes the supplier -> assets relationship
|
||||||
|
|
|
@ -65,6 +65,7 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
|
||||||
'avatar',
|
'avatar',
|
||||||
'gravatar',
|
'gravatar',
|
||||||
'vip',
|
'vip',
|
||||||
|
'autoassign_licenses',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $casts = [
|
protected $casts = [
|
||||||
|
@ -76,6 +77,7 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
|
||||||
'created_at' => 'datetime',
|
'created_at' => 'datetime',
|
||||||
'updated_at' => 'datetime',
|
'updated_at' => 'datetime',
|
||||||
'deleted_at' => 'datetime',
|
'deleted_at' => 'datetime',
|
||||||
|
'autoassign_licenses' => 'boolean',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -95,6 +97,7 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
|
||||||
'location_id' => 'exists:locations,id|nullable',
|
'location_id' => 'exists:locations,id|nullable',
|
||||||
'start_date' => 'nullable|date_format:Y-m-d',
|
'start_date' => 'nullable|date_format:Y-m-d',
|
||||||
'end_date' => 'nullable|date_format:Y-m-d|after_or_equal:start_date',
|
'end_date' => 'nullable|date_format:Y-m-d|after_or_equal:start_date',
|
||||||
|
'autoassign_licenses' => 'boolean',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -256,20 +259,6 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
|
||||||
return $this->last_name.', '.$this->first_name.' ('.$this->username.')';
|
return $this->last_name.', '.$this->first_name.' ('.$this->username.')';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* The url for slack notifications.
|
|
||||||
* Used by Notifiable trait.
|
|
||||||
* @return mixed
|
|
||||||
*/
|
|
||||||
public function routeNotificationForSlack()
|
|
||||||
{
|
|
||||||
// At this point the endpoint is the same for everything.
|
|
||||||
// In the future this may want to be adapted for individual notifications.
|
|
||||||
$this->endpoint = \App\Models\Setting::getSettings()->webhook_endpoint;
|
|
||||||
|
|
||||||
return $this->endpoint;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Establishes the user -> assets relationship
|
* Establishes the user -> assets relationship
|
||||||
|
|
|
@ -534,6 +534,18 @@ class AssetPresenter extends Presenter
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to take user created warranty URL and dynamically fill in the needed values per asset
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function dynamicWarrantyUrl()
|
||||||
|
{
|
||||||
|
$warranty_lookup_url = $this->model->model->manufacturer->warranty_lookup_url;
|
||||||
|
$url = (str_replace('{LOCALE}',\App\Models\Setting::getSettings()->locale,$warranty_lookup_url));
|
||||||
|
$url = (str_replace('{SERIAL}',$this->model->serial,$url));
|
||||||
|
return $url;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Url to view this item.
|
* Url to view this item.
|
||||||
* @return string
|
* @return string
|
||||||
|
|
|
@ -33,7 +33,7 @@ class LicensePresenter extends Presenter
|
||||||
'field' => 'name',
|
'field' => 'name',
|
||||||
'searchable' => true,
|
'searchable' => true,
|
||||||
'sortable' => true,
|
'sortable' => true,
|
||||||
'title' => trans('admin/licenses/table.title'),
|
'title' => trans('general.name'),
|
||||||
'formatter' => 'licensesLinkFormatter',
|
'formatter' => 'licensesLinkFormatter',
|
||||||
], [
|
], [
|
||||||
'field' => 'product_key',
|
'field' => 'product_key',
|
||||||
|
|
|
@ -47,7 +47,7 @@ class ManufacturerPresenter extends Presenter
|
||||||
'switchable' => true,
|
'switchable' => true,
|
||||||
'title' => trans('admin/manufacturers/table.url'),
|
'title' => trans('admin/manufacturers/table.url'),
|
||||||
'visible' => true,
|
'visible' => true,
|
||||||
'formatter' => 'linkFormatter',
|
'formatter' => 'externalLinkFormatter',
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'field' => 'support_url',
|
'field' => 'support_url',
|
||||||
|
@ -56,7 +56,7 @@ class ManufacturerPresenter extends Presenter
|
||||||
'switchable' => true,
|
'switchable' => true,
|
||||||
'title' => trans('admin/manufacturers/table.support_url'),
|
'title' => trans('admin/manufacturers/table.support_url'),
|
||||||
'visible' => true,
|
'visible' => true,
|
||||||
'formatter' => 'linkFormatter',
|
'formatter' => 'externalLinkFormatter',
|
||||||
],
|
],
|
||||||
|
|
||||||
[
|
[
|
||||||
|
@ -78,6 +78,15 @@ class ManufacturerPresenter extends Presenter
|
||||||
'visible' => true,
|
'visible' => true,
|
||||||
'formatter' => 'emailFormatter',
|
'formatter' => 'emailFormatter',
|
||||||
],
|
],
|
||||||
|
[
|
||||||
|
'field' => 'warranty_lookup_url',
|
||||||
|
'searchable' => true,
|
||||||
|
'sortable' => true,
|
||||||
|
'switchable' => true,
|
||||||
|
'title' => trans('admin/manufacturers/table.warranty_lookup_url'),
|
||||||
|
'visible' => false,
|
||||||
|
'formatter' => 'externalLinkFormatter',
|
||||||
|
],
|
||||||
|
|
||||||
[
|
[
|
||||||
'field' => 'assets_count',
|
'field' => 'assets_count',
|
||||||
|
|
|
@ -294,6 +294,15 @@ class UserPresenter extends Presenter
|
||||||
'visible' => true,
|
'visible' => true,
|
||||||
'formatter' => 'trueFalseFormatter',
|
'formatter' => 'trueFalseFormatter',
|
||||||
],
|
],
|
||||||
|
[
|
||||||
|
'field' => 'autoassign_licenses',
|
||||||
|
'searchable' => false,
|
||||||
|
'sortable' => true,
|
||||||
|
'switchable' => true,
|
||||||
|
'title' => trans('general.autoassign_licenses'),
|
||||||
|
'visible' => false,
|
||||||
|
'formatter' => 'trueFalseFormatter',
|
||||||
|
],
|
||||||
[
|
[
|
||||||
'field' => 'created_by',
|
'field' => 'created_by',
|
||||||
'searchable' => false,
|
'searchable' => false,
|
||||||
|
|
|
@ -130,7 +130,7 @@ return [
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'path' => '/',
|
'path' => env('SESSION_COOKIE_PATH', '/'),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
|
16
database/factories/LicenseSeatFactory.php
Normal file
16
database/factories/LicenseSeatFactory.php
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Database\Factories;
|
||||||
|
|
||||||
|
use App\Models\License;
|
||||||
|
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||||
|
|
||||||
|
class LicenseSeatFactory extends Factory
|
||||||
|
{
|
||||||
|
public function definition()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'license_id' => License::factory(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
|
@ -38,6 +38,7 @@ class ManufacturerFactory extends Factory
|
||||||
'name' => 'Apple',
|
'name' => 'Apple',
|
||||||
'url' => 'https://apple.com',
|
'url' => 'https://apple.com',
|
||||||
'support_url' => 'https://support.apple.com',
|
'support_url' => 'https://support.apple.com',
|
||||||
|
'warranty_lookup_url' => 'https://checkcoverage.apple.com',
|
||||||
'image' => 'apple.jpg',
|
'image' => 'apple.jpg',
|
||||||
];
|
];
|
||||||
});
|
});
|
||||||
|
@ -50,6 +51,7 @@ class ManufacturerFactory extends Factory
|
||||||
'name' => 'Microsoft',
|
'name' => 'Microsoft',
|
||||||
'url' => 'https://microsoft.com',
|
'url' => 'https://microsoft.com',
|
||||||
'support_url' => 'https://support.microsoft.com',
|
'support_url' => 'https://support.microsoft.com',
|
||||||
|
'warranty_lookup_url' => 'https://account.microsoft.com/devices',
|
||||||
'image' => 'microsoft.png',
|
'image' => 'microsoft.png',
|
||||||
];
|
];
|
||||||
});
|
});
|
||||||
|
@ -62,6 +64,7 @@ class ManufacturerFactory extends Factory
|
||||||
'name' => 'Dell',
|
'name' => 'Dell',
|
||||||
'url' => 'https://dell.com',
|
'url' => 'https://dell.com',
|
||||||
'support_url' => 'https://support.dell.com',
|
'support_url' => 'https://support.dell.com',
|
||||||
|
'warranty_lookup_url' => 'https://www.dell.com/support/home/en-us/Products/?app=warranty',
|
||||||
'image' => 'dell.png',
|
'image' => 'dell.png',
|
||||||
];
|
];
|
||||||
});
|
});
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
class AddsLdapLocationToSettingsTable extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::table('settings', function (Blueprint $table) {
|
||||||
|
$table->string('ldap_location')->after('ldap_country')->nullable()->default(null);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::table('settings', function (Blueprint $table) {
|
||||||
|
$table->dropColumn('ldap_location');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
class AddWarrantyUrlToManufacturers extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::table('manufacturers', function (Blueprint $table) {
|
||||||
|
$table->string('warranty_lookup_url')->after('support_url')->nullable()->default(null);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::table('manufacturers', function (Blueprint $table) {
|
||||||
|
$table->dropColumn('warranty_lookup_url');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
12
package-lock.json
generated
12
package-lock.json
generated
|
@ -1329,9 +1329,9 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"@fortawesome/fontawesome-free": {
|
"@fortawesome/fontawesome-free": {
|
||||||
"version": "6.3.0",
|
"version": "6.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-6.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-6.4.0.tgz",
|
||||||
"integrity": "sha512-qVtd5i1Cc7cdrqnTWqTObKQHjPWAiRwjUPaXObaeNPcy7+WKxJumGBx66rfSFgK6LNpIasVKkEgW8oyf0tmPLA=="
|
"integrity": "sha512-0NyytTlPJwB/BF5LtRV8rrABDbe3TdTXqNB3PdZ+UUUZAEIrdOJdmABqKjt4AXwIoJNaRVVZEXxpNrqvE1GAYQ=="
|
||||||
},
|
},
|
||||||
"@jridgewell/gen-mapping": {
|
"@jridgewell/gen-mapping": {
|
||||||
"version": "0.1.1",
|
"version": "0.1.1",
|
||||||
|
@ -3154,9 +3154,9 @@
|
||||||
"integrity": "sha1-EQPWvADPv6jPyaJZmrUYxVZD2j8="
|
"integrity": "sha1-EQPWvADPv6jPyaJZmrUYxVZD2j8="
|
||||||
},
|
},
|
||||||
"bootstrap-table": {
|
"bootstrap-table": {
|
||||||
"version": "1.21.3",
|
"version": "1.21.4",
|
||||||
"resolved": "https://registry.npmjs.org/bootstrap-table/-/bootstrap-table-1.21.3.tgz",
|
"resolved": "https://registry.npmjs.org/bootstrap-table/-/bootstrap-table-1.21.4.tgz",
|
||||||
"integrity": "sha512-y6PLHxJJVqIVXoMWrnwPsA8dKqvy9An8Iz7WuuimuLU1i0jIT9+Xzg6NXqBBilHOwp0dUAw9vfgNLvCVq2wdJQ=="
|
"integrity": "sha512-Vp0kwkCsZzBINiA1KJ46LSkIa4oA0r6GSuzERZEqkUU8/0JDij2aG4CdYxiOm/UFCPZ9+KuAE4zSjxJLxg5jWw=="
|
||||||
},
|
},
|
||||||
"brace-expansion": {
|
"brace-expansion": {
|
||||||
"version": "1.1.11",
|
"version": "1.1.11",
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
"vue-template-compiler": "2.4.4"
|
"vue-template-compiler": "2.4.4"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fortawesome/fontawesome-free": "^6.3.0",
|
"@fortawesome/fontawesome-free": "^6.4.0",
|
||||||
"acorn": "^8.8.2",
|
"acorn": "^8.8.2",
|
||||||
"acorn-import-assertions": "^1.8.0",
|
"acorn-import-assertions": "^1.8.0",
|
||||||
"admin-lte": "^2.4.18",
|
"admin-lte": "^2.4.18",
|
||||||
|
@ -34,7 +34,7 @@
|
||||||
"bootstrap-colorpicker": "^2.5.3",
|
"bootstrap-colorpicker": "^2.5.3",
|
||||||
"bootstrap-datepicker": "^1.9.0",
|
"bootstrap-datepicker": "^1.9.0",
|
||||||
"bootstrap-less": "^3.3.8",
|
"bootstrap-less": "^3.3.8",
|
||||||
"bootstrap-table": "1.21.3",
|
"bootstrap-table": "1.21.4",
|
||||||
"chart.js": "^2.9.4",
|
"chart.js": "^2.9.4",
|
||||||
"css-loader": "^4.0.0",
|
"css-loader": "^4.0.0",
|
||||||
"ekko-lightbox": "^5.1.1",
|
"ekko-lightbox": "^5.1.1",
|
||||||
|
@ -54,6 +54,6 @@
|
||||||
"tableexport.jquery.plugin": "1.27.0",
|
"tableexport.jquery.plugin": "1.27.0",
|
||||||
"tether": "^1.4.0",
|
"tether": "^1.4.0",
|
||||||
"vue-resource": "^1.5.2",
|
"vue-resource": "^1.5.2",
|
||||||
"webpack": "^5.76.2"
|
"webpack": "^5.77.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
BIN
public/css/dist/all.css
vendored
BIN
public/css/dist/all.css
vendored
Binary file not shown.
BIN
public/css/dist/bootstrap-table.css
vendored
BIN
public/css/dist/bootstrap-table.css
vendored
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
public/js/dist/bootstrap-table.js
vendored
BIN
public/js/dist/bootstrap-table.js
vendored
Binary file not shown.
|
@ -18,20 +18,20 @@
|
||||||
"/css/dist/skins/skin-green.css": "/css/dist/skins/skin-green.css?id=0a82a6ae6bb4e58fe62d162c4fb50397",
|
"/css/dist/skins/skin-green.css": "/css/dist/skins/skin-green.css?id=0a82a6ae6bb4e58fe62d162c4fb50397",
|
||||||
"/css/dist/skins/skin-contrast.css": "/css/dist/skins/skin-contrast.css?id=da6c7997d9de2f8329142399f0ce50da",
|
"/css/dist/skins/skin-contrast.css": "/css/dist/skins/skin-contrast.css?id=da6c7997d9de2f8329142399f0ce50da",
|
||||||
"/css/dist/skins/skin-red.css": "/css/dist/skins/skin-red.css?id=44bf834f2110504a793dadec132a5898",
|
"/css/dist/skins/skin-red.css": "/css/dist/skins/skin-red.css?id=44bf834f2110504a793dadec132a5898",
|
||||||
"/css/dist/all.css": "/css/dist/all.css?id=2b87a5b5f1e6f09861732fa41d159bc4",
|
"/css/dist/all.css": "/css/dist/all.css?id=41d8a74912c3b0d17cc508361530c597",
|
||||||
"/css/dist/signature-pad.css": "/css/dist/signature-pad.css?id=6a89d3cd901305e66ced1cf5f13147f7",
|
"/css/dist/signature-pad.css": "/css/dist/signature-pad.css?id=6a89d3cd901305e66ced1cf5f13147f7",
|
||||||
"/css/dist/signature-pad.min.css": "/css/dist/signature-pad.min.css?id=6a89d3cd901305e66ced1cf5f13147f7",
|
"/css/dist/signature-pad.min.css": "/css/dist/signature-pad.min.css?id=6a89d3cd901305e66ced1cf5f13147f7",
|
||||||
"/css/webfonts/fa-brands-400.ttf": "/css/webfonts/fa-brands-400.ttf?id=2df05d4beaa48550d71234e8dca79141",
|
"/css/webfonts/fa-brands-400.ttf": "/css/webfonts/fa-brands-400.ttf?id=e2e2b1797606a266ed55549f5bb5a179",
|
||||||
"/css/webfonts/fa-brands-400.woff2": "/css/webfonts/fa-brands-400.woff2?id=682885a4f72597322017a9fcd0683831",
|
"/css/webfonts/fa-brands-400.woff2": "/css/webfonts/fa-brands-400.woff2?id=fe912d1c4a7e0e1db87a64eb7e54c945",
|
||||||
"/css/webfonts/fa-regular-400.ttf": "/css/webfonts/fa-regular-400.ttf?id=e7a7f9dd9376f68614860d920255d4df",
|
"/css/webfonts/fa-regular-400.ttf": "/css/webfonts/fa-regular-400.ttf?id=31a6b5ecfc8d018d0e3a294f0c80e9e9",
|
||||||
"/css/webfonts/fa-regular-400.woff2": "/css/webfonts/fa-regular-400.woff2?id=204fc700c679395e6aa9bebc3cada64e",
|
"/css/webfonts/fa-regular-400.woff2": "/css/webfonts/fa-regular-400.woff2?id=bf8eabe300a00a3adb0293596987abc4",
|
||||||
"/css/webfonts/fa-solid-900.ttf": "/css/webfonts/fa-solid-900.ttf?id=c9d3294ec75b843a31ef711069a0f0b6",
|
"/css/webfonts/fa-solid-900.ttf": "/css/webfonts/fa-solid-900.ttf?id=cd687455c6d6c058e2e9f84f409e2965",
|
||||||
"/css/webfonts/fa-solid-900.woff2": "/css/webfonts/fa-solid-900.woff2?id=6707d0247b0bca1b4964bab435e3c0d6",
|
"/css/webfonts/fa-solid-900.woff2": "/css/webfonts/fa-solid-900.woff2?id=eea38615e7b5dbbaf88c263f2230cc32",
|
||||||
"/css/webfonts/fa-v4compatibility.ttf": "/css/webfonts/fa-v4compatibility.ttf?id=a947172f4fde88e43b4c1a60b01db061",
|
"/css/webfonts/fa-v4compatibility.ttf": "/css/webfonts/fa-v4compatibility.ttf?id=6ebbf5afc34f54463abc2b81ca637364",
|
||||||
"/css/webfonts/fa-v4compatibility.woff2": "/css/webfonts/fa-v4compatibility.woff2?id=bbc23038a6067c78310d3f19432a3ebf",
|
"/css/webfonts/fa-v4compatibility.woff2": "/css/webfonts/fa-v4compatibility.woff2?id=67b8a78b7e80e805cfa4ee0421895ba4",
|
||||||
"/css/dist/bootstrap-table.css": "/css/dist/bootstrap-table.css?id=418917c053841ab1aa1b78610a1825e0",
|
"/css/dist/bootstrap-table.css": "/css/dist/bootstrap-table.css?id=2265e072e44c782c901dce8e037d97fc",
|
||||||
"/js/build/vendor.js": "/js/build/vendor.js?id=3843eca1b2e670b29c1e1cb57e1d7aa7",
|
"/js/build/vendor.js": "/js/build/vendor.js?id=3843eca1b2e670b29c1e1cb57e1d7aa7",
|
||||||
"/js/dist/bootstrap-table.js": "/js/dist/bootstrap-table.js?id=7a506bf59323cf5b5fe97f7080fc5ee0",
|
"/js/dist/bootstrap-table.js": "/js/dist/bootstrap-table.js?id=a0e44dba789031b34ef150a01318b865",
|
||||||
"/js/dist/all.js": "/js/dist/all.js?id=97b1034b75e3ac29a2eb9770d66c3370",
|
"/js/dist/all.js": "/js/dist/all.js?id=97b1034b75e3ac29a2eb9770d66c3370",
|
||||||
"/css/dist/skins/skin-green.min.css": "/css/dist/skins/skin-green.min.css?id=0a82a6ae6bb4e58fe62d162c4fb50397",
|
"/css/dist/skins/skin-green.min.css": "/css/dist/skins/skin-green.min.css?id=0a82a6ae6bb4e58fe62d162c4fb50397",
|
||||||
"/css/dist/skins/skin-green-dark.min.css": "/css/dist/skins/skin-green-dark.min.css?id=28b36223cf7b1d6e5f236859a4ef2b45",
|
"/css/dist/skins/skin-green-dark.min.css": "/css/dist/skins/skin-green-dark.min.css?id=28b36223cf7b1d6e5f236859a4ef2b45",
|
||||||
|
|
|
@ -23,6 +23,7 @@ return [
|
||||||
'restore' => 'Restore Asset',
|
'restore' => 'Restore Asset',
|
||||||
'pending' => 'Pending',
|
'pending' => 'Pending',
|
||||||
'undeployable' => 'Undeployable',
|
'undeployable' => 'Undeployable',
|
||||||
|
'undeployable_tooltip' => 'This asset has a status label that is undeployable and cannot be checked out at this time.',
|
||||||
'view' => 'View Asset',
|
'view' => 'View Asset',
|
||||||
'csv_error' => 'You have an error in your CSV file:',
|
'csv_error' => 'You have an error in your CSV file:',
|
||||||
'import_text' => '
|
'import_text' => '
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
'about_licenses_title' => 'About Licenses',
|
'about_licenses_title' => 'About Licenses',
|
||||||
'about_licenses' => 'Licenses are used to track software. They have a specified number of seats that can be checked out to individuals',
|
'about_licenses' => 'Licenses are used to track software. They have a specified number of seats that can be checked out to individuals',
|
||||||
'checkin' => 'Checkin License Seat',
|
'checkin' => 'Checkin License Seat',
|
||||||
'checkout_history' => 'Checkout History',
|
'checkout_history' => 'Checkout History',
|
||||||
'checkout' => 'Checkout License Seat',
|
'checkout' => 'Checkout License Seat',
|
||||||
|
@ -18,4 +18,30 @@ return array(
|
||||||
'software_licenses' => 'Software Licenses',
|
'software_licenses' => 'Software Licenses',
|
||||||
'user' => 'User',
|
'user' => 'User',
|
||||||
'view' => 'View License',
|
'view' => 'View License',
|
||||||
|
'delete_disabled' => 'This license cannot be deleted yet because some seats are still checked out.',
|
||||||
|
'bulk' =>
|
||||||
|
[
|
||||||
|
'checkin_all' => [
|
||||||
|
'button' => 'Checkin All Seats',
|
||||||
|
'modal' => 'This will action checkin one seat. | This action will checkin all :checkedout_seats_count seats for this license.',
|
||||||
|
'enabled_tooltip' => 'Checkin ALL seats for this license from both users and assets',
|
||||||
|
'disabled_tooltip' => 'This is disabled because there are no seats currently checked out',
|
||||||
|
'success' => 'License successfully checked in! | All licenses were successfully checked in!',
|
||||||
|
'log_msg' => 'Checked in via bulk license checkout in license GUI',
|
||||||
|
],
|
||||||
|
|
||||||
|
'checkout_all' => [
|
||||||
|
'button' => 'Checkout All Seats',
|
||||||
|
'modal' => 'This action will checkout one seat to the first available user. | This action will checkout all :available_seats_count seats to the first available users. A user is considered available for this seat if they do not already have this license checked out to them, and the Auto-Assign License property is enabled on their user account.',
|
||||||
|
'enabled_tooltip' => 'Checkout ALL seats (or as many as are available) to ALL users',
|
||||||
|
'disabled_tooltip' => 'This is disabled because there are no seats currently available',
|
||||||
|
'success' => 'License successfully checked out! | :count licenses were successfully checked out!',
|
||||||
|
'error_no_seats' => 'There are no remaining seats left for this license.',
|
||||||
|
'warn_not_enough_seats' => ':count users were assigned this license, but we ran out of available license seats.',
|
||||||
|
'warn_no_avail_users' => 'Nothing to do. There are no users who do not already have this license assigned to them.',
|
||||||
|
'log_msg' => 'Checked out via bulk license checkout in license GUI',
|
||||||
|
|
||||||
|
|
||||||
|
],
|
||||||
|
],
|
||||||
);
|
);
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
|
|
||||||
|
'support_url_help' => 'Use <code>{LOCALE}</code> and <code>{SERIAL}</code> in your URL as variables to have those values auto-populate when viewing assets.',
|
||||||
'does_not_exist' => 'Manufacturer does not exist.',
|
'does_not_exist' => 'Manufacturer does not exist.',
|
||||||
'assoc_users' => 'This manufacturer is currently associated with at least one model and cannot be deleted. Please update your models to no longer reference this manufacturer and try again. ',
|
'assoc_users' => 'This manufacturer is currently associated with at least one model and cannot be deleted. Please update your models to no longer reference this manufacturer and try again. ',
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ return array(
|
||||||
'support_email' => 'Support Email',
|
'support_email' => 'Support Email',
|
||||||
'support_phone' => 'Support Phone',
|
'support_phone' => 'Support Phone',
|
||||||
'support_url' => 'Support URL',
|
'support_url' => 'Support URL',
|
||||||
|
'warranty_lookup_url' => 'Warranty Lookup URL',
|
||||||
'update' => 'Update Manufacturer',
|
'update' => 'Update Manufacturer',
|
||||||
'url' => 'URL',
|
'url' => 'URL',
|
||||||
|
|
||||||
|
|
|
@ -86,6 +86,8 @@ return [
|
||||||
'ldap_settings' => 'LDAP Settings',
|
'ldap_settings' => 'LDAP Settings',
|
||||||
'ldap_client_tls_cert_help' => 'Client-Side TLS Certificate and Key for LDAP connections are usually only useful in Google Workspace configurations with "Secure LDAP." Both are required.',
|
'ldap_client_tls_cert_help' => 'Client-Side TLS Certificate and Key for LDAP connections are usually only useful in Google Workspace configurations with "Secure LDAP." Both are required.',
|
||||||
'ldap_client_tls_key' => 'LDAP Client-Side TLS key',
|
'ldap_client_tls_key' => 'LDAP Client-Side TLS key',
|
||||||
|
'ldap_location' => 'LDAP Location',
|
||||||
|
'ldap_location_help' => 'The Ldap Location field should be used if <strong>an OU is not being used in the Base Bind DN.</strong> Leave this blank if an OU search is being used.',
|
||||||
'ldap_login_test_help' => 'Enter a valid LDAP username and password from the base DN you specified above to test whether your LDAP login is configured correctly. YOU MUST SAVE YOUR UPDATED LDAP SETTINGS FIRST.',
|
'ldap_login_test_help' => 'Enter a valid LDAP username and password from the base DN you specified above to test whether your LDAP login is configured correctly. YOU MUST SAVE YOUR UPDATED LDAP SETTINGS FIRST.',
|
||||||
'ldap_login_sync_help' => 'This only tests that LDAP can sync correctly. If your LDAP Authentication query is not correct, users may still not be able to login. YOU MUST SAVE YOUR UPDATED LDAP SETTINGS FIRST.',
|
'ldap_login_sync_help' => 'This only tests that LDAP can sync correctly. If your LDAP Authentication query is not correct, users may still not be able to login. YOU MUST SAVE YOUR UPDATED LDAP SETTINGS FIRST.',
|
||||||
'ldap_manager' => 'LDAP Manager',
|
'ldap_manager' => 'LDAP Manager',
|
||||||
|
|
|
@ -439,4 +439,13 @@ return [
|
||||||
'setup_migration_output' => 'Migration output:',
|
'setup_migration_output' => 'Migration output:',
|
||||||
'setup_migration_create_user' => 'Next: Create User',
|
'setup_migration_create_user' => 'Next: Create User',
|
||||||
'importer_generic_error' => 'Your file import is complete, but we did receive an error. This is usually caused by third-party API throttling from a notification webhook (such as Slack) and would not have interfered with the import itself, but you should confirm this.',
|
'importer_generic_error' => 'Your file import is complete, but we did receive an error. This is usually caused by third-party API throttling from a notification webhook (such as Slack) and would not have interfered with the import itself, but you should confirm this.',
|
||||||
|
'confirm' => 'Confirm',
|
||||||
|
'autoassign_licenses' => 'Auto-Assign Licenses',
|
||||||
|
'autoassign_licenses_help' => 'Allow user to be have licenses assigned via the bulk-assign license UI or cli tools.',
|
||||||
|
'autoassign_licenses_help_long' => 'This allows a user to be have licenses assigned via the bulk-assign license UI or cli tools. (For example, you might not want contractors to be auto-assigned a license you would provide to only staff members. You can still individually assign licenses to those users, but they will not be included in the Checkout License to All Users functions.)',
|
||||||
|
'no_autoassign_licenses_help' => 'Do not include user for bulk-assigning through the license UI or cli tools.',
|
||||||
|
'modal_confirm_generic' => 'Are you sure?',
|
||||||
|
'cannot_be_deleted' => 'This item cannot be deleted',
|
||||||
|
'undeployable_tooltip' => 'This item cannot be checked out. Check the quantity remaining.',
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
<h2 class="box-title">{{ trans('admin/custom_fields/general.fieldsets') }}</h2>
|
<h2 class="box-title">{{ trans('admin/custom_fields/general.fieldsets') }}</h2>
|
||||||
<div class="box-tools pull-right">
|
<div class="box-tools pull-right">
|
||||||
@can('create', \App\Models\CustomFieldset::class)
|
@can('create', \App\Models\CustomFieldset::class)
|
||||||
<a href="{{ route('fieldsets.create') }}" class="btn btn-sm btn-primary" data-toggle="tooltip" title="{{ trans('admin/custom_fields/general.create_fieldset_title') }}">{{ trans('admin/custom_fields/general.create_fieldset') }}</a>
|
<a href="{{ route('fieldsets.create') }}" class="btn btn-sm btn-primary" data-tooltip="true" title="{{ trans('admin/custom_fields/general.create_fieldset_title') }}">{{ trans('admin/custom_fields/general.create_fieldset') }}</a>
|
||||||
@endcan
|
@endcan
|
||||||
</div>
|
</div>
|
||||||
</div><!-- /.box-header -->
|
</div><!-- /.box-header -->
|
||||||
|
@ -111,7 +111,7 @@
|
||||||
<h2 class="box-title">{{ trans('admin/custom_fields/general.custom_fields') }}</h2>
|
<h2 class="box-title">{{ trans('admin/custom_fields/general.custom_fields') }}</h2>
|
||||||
<div class="box-tools pull-right">
|
<div class="box-tools pull-right">
|
||||||
@can('create', \App\Models\CustomField::class)
|
@can('create', \App\Models\CustomField::class)
|
||||||
<a href="{{ route('fields.create') }}" class="btn btn-sm btn-primary" data-toggle="tooltip" title="{{ trans('admin/custom_fields/general.create_field_title') }}">{{ trans('admin/custom_fields/general.create_field') }}</a>
|
<a href="{{ route('fields.create') }}" class="btn btn-sm btn-primary" data-tooltip="true" title="{{ trans('admin/custom_fields/general.create_field_title') }}">{{ trans('admin/custom_fields/general.create_field') }}</a>
|
||||||
@endcan
|
@endcan
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -77,7 +77,7 @@
|
||||||
<tbody class="permissions-group">
|
<tbody class="permissions-group">
|
||||||
<tr class="header-row permissions-row">
|
<tr class="header-row permissions-row">
|
||||||
<td class="col-md-5 tooltip-base permissions-item"
|
<td class="col-md-5 tooltip-base permissions-item"
|
||||||
data-toggle="tooltip"
|
data-tooltip="true"
|
||||||
data-placement="right"
|
data-placement="right"
|
||||||
title="{{ $localPermission['note'] }}">
|
title="{{ $localPermission['note'] }}">
|
||||||
@unless (empty($localPermission['label']))
|
@unless (empty($localPermission['label']))
|
||||||
|
@ -100,7 +100,7 @@
|
||||||
<tbody class="permission-group">
|
<tbody class="permission-group">
|
||||||
<tr class="header-row permissions-row">
|
<tr class="header-row permissions-row">
|
||||||
<td class="col-md-5 tooltip-base permissions-item header-name"
|
<td class="col-md-5 tooltip-base permissions-item header-name"
|
||||||
data-toggle="tooltip"
|
data-tooltip="true"
|
||||||
data-placement="right"
|
data-placement="right"
|
||||||
title="{{ $localPermission['note'] }}">
|
title="{{ $localPermission['note'] }}">
|
||||||
<h2>{{ $area }}</h2>
|
<h2>{{ $area }}</h2>
|
||||||
|
@ -122,7 +122,7 @@
|
||||||
<tr class="permissions-row">
|
<tr class="permissions-row">
|
||||||
<td
|
<td
|
||||||
class="col-md-5 tooltip-base permissions-item"
|
class="col-md-5 tooltip-base permissions-item"
|
||||||
data-toggle="tooltip"
|
data-tooltip="true"
|
||||||
data-placement="right"
|
data-placement="right"
|
||||||
title="{{ $this_permission['note'] }}">
|
title="{{ $this_permission['note'] }}">
|
||||||
{{ $this_permission['label'] }}
|
{{ $this_permission['label'] }}
|
||||||
|
|
|
@ -456,7 +456,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-6{{ (($field->format=='URL') && ($asset->{$field->db_column_name()}!='')) ? ' ellipsis': '' }}">
|
<div class="col-md-6{{ (($field->format=='URL') && ($asset->{$field->db_column_name()}!='')) ? ' ellipsis': '' }}">
|
||||||
@if ($field->field_encrypted=='1')
|
@if ($field->field_encrypted=='1')
|
||||||
<i class="fas fa-lock" data-toggle="tooltip" data-placement="top" title="{{ trans('admin/custom_fields/general.value_encrypted') }}"></i>
|
<i class="fas fa-lock" data-tooltip="true" data-placement="top" title="{{ trans('admin/custom_fields/general.value_encrypted') }}"></i>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
@if ($field->isFieldDecryptable($asset->{$field->db_column_name()} ))
|
@if ($field->isFieldDecryptable($asset->{$field->db_column_name()} ))
|
||||||
|
@ -595,20 +595,10 @@
|
||||||
{{ $asset->warranty_months }}
|
{{ $asset->warranty_months }}
|
||||||
{{ trans('admin/hardware/form.months') }}
|
{{ trans('admin/hardware/form.months') }}
|
||||||
|
|
||||||
@if ($asset->serial && $asset->model->manufacturer)
|
@if (($asset->model->manufacturer) && ($asset->model->manufacturer->warranty_lookup_url!=''))
|
||||||
@if ((strtolower($asset->model->manufacturer->name) == "apple") || (str_starts_with(str_replace(' ','',strtolower($asset->model->manufacturer->name)),"appleinc")))
|
<a href="{{ $asset->present()->dynamicWarrantyUrl() }}" target="_blank">
|
||||||
<a href="https://checkcoverage.apple.com/?locale={{ (str_replace('-','_',\App\Models\Setting::getSettings()->locale)) }}" target="_blank">
|
<i class="fa fa-external-link"><span class="sr-only">{{ trans('admin/hardware/general.mfg_warranty_lookup', ['manufacturer' => $asset->model->manufacturer->name]) }}</span></i>
|
||||||
<i class="fa-brands fa-apple" aria-hidden="true"><span class="sr-only">{{ trans('hardware/general.mfg_warranty_lookup') }}</span></i>
|
|
||||||
</a>
|
</a>
|
||||||
@elseif ((strtolower($asset->model->manufacturer->name) == "dell") || (str_starts_with(str_replace(' ','',strtolower($asset->model->manufacturer->name)),"dellinc")))
|
|
||||||
<a href="https://www.dell.com/support/home/en-us?app=warranty" target="_blank">
|
|
||||||
<img src="/img/demo/manufacturers/dellicon.png" style="width:25px;height:25px;"><span class="sr-only">{{ trans('hardware/general.mfg_warranty_lookup') }}</span></i>
|
|
||||||
</a>
|
|
||||||
@elseif ((strtolower($asset->model->manufacturer->name) == "lenovo") || (str_starts_with(str_replace(' ','',strtolower($asset->model->manufacturer->name)),"lenovoinc")))
|
|
||||||
<a href="https://pcsupport.lenovo.com/us/en/warrantylookup#/" target="_blank">
|
|
||||||
<img src="/img/demo/manufacturers/lenovoicon.png" style="width:25px;height:25px;"><span class="sr-only">{{ trans('hardware/general.mfg_warranty_lookup') }}</span></i>
|
|
||||||
</a>
|
|
||||||
@endif
|
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -483,8 +483,7 @@
|
||||||
class="fas fa-times text-red fa-fw"></i>
|
class="fas fa-times text-red fa-fw"></i>
|
||||||
{{ trans('general.all') }}
|
{{ trans('general.all') }}
|
||||||
{{ trans('general.undeployable') }}
|
{{ trans('general.undeployable') }}
|
||||||
({{ (isset($total_undeployable_sidebar)) ? $total_undeployable_sidebar : '' }}
|
({{ (isset($total_undeployable_sidebar)) ? $total_undeployable_sidebar : '' }})
|
||||||
)
|
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li{!! (Request::query('status') == 'byod' ? ' class="active"' : '') !!}><a
|
<li{!! (Request::query('status') == 'byod' ? ' class="active"' : '') !!}><a
|
||||||
|
@ -974,7 +973,7 @@
|
||||||
|
|
||||||
$(function () {
|
$(function () {
|
||||||
|
|
||||||
$('[data-toggle="tooltip"]').tooltip();
|
$('[data-tooltip="true"]').tooltip();
|
||||||
$('[data-toggle="popover"]').popover();
|
$('[data-toggle="popover"]').popover();
|
||||||
$('.select2 span').addClass('needsclick');
|
$('.select2 span').addClass('needsclick');
|
||||||
$('.select2 span').removeAttr('title');
|
$('.select2 span').removeAttr('title');
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
{{-- Page content --}}
|
{{-- Page content --}}
|
||||||
@section('content')
|
@section('content')
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-12">
|
<div class="col-md-9">
|
||||||
|
|
||||||
<!-- Custom Tabs -->
|
<!-- Custom Tabs -->
|
||||||
<div class="nav-tabs-custom">
|
<div class="nav-tabs-custom">
|
||||||
|
@ -57,20 +57,6 @@
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
@can('update', $license)
|
|
||||||
<li class="dropdown pull-right">
|
|
||||||
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
|
|
||||||
<i class="fas fa-cog" aria-hidden="true"></i> {{ trans('button.actions') }}
|
|
||||||
<span class="caret"></span>
|
|
||||||
</a>
|
|
||||||
<ul class="dropdown-menu">
|
|
||||||
<li><a href="{{ route('licenses.edit', $license->id) }}">{{ trans('admin/licenses/general.edit') }}</a></li>
|
|
||||||
<li><a href="{{ route('clone/license', $license->id) }}">{{ trans('admin/licenses/general.clone') }}</a></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
@endcan
|
|
||||||
|
|
||||||
@can('update', \App\Models\License::class)
|
@can('update', \App\Models\License::class)
|
||||||
<li class="pull-right"><a href="#" data-toggle="modal" data-target="#uploadFileModal">
|
<li class="pull-right"><a href="#" data-toggle="modal" data-target="#uploadFileModal">
|
||||||
<i class="fas fa-paperclip" aria-hidden="true"></i> {{ trans('button.upload') }}</a>
|
<i class="fas fa-paperclip" aria-hidden="true"></i> {{ trans('button.upload') }}</a>
|
||||||
|
@ -332,7 +318,7 @@
|
||||||
</strong>
|
</strong>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-9">
|
<div class="col-md-9">
|
||||||
{!! $license->maintained ? '<i class="fas fa-check text-success" aria-hidden="true"></i> '.trans('general.yes') : '<i class="fas fa-times text-danger" aria-hidden="true"></i> '.trans('general.no') !!}
|
{!! $license->maintained ? '<i class="fas fa-check fa-fw text-success" aria-hidden="true"></i> '.trans('general.yes') : '<i class="fas fa-times fa-fw text-danger" aria-hidden="true"></i> '.trans('general.no') !!}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -358,7 +344,7 @@
|
||||||
</strong>
|
</strong>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-9">
|
<div class="col-md-9">
|
||||||
{!! $license->reassignable ? '<i class="fas fa-check text-success" aria-hidden="true"></i> '.trans('general.yes') : '<i class="fas fa-times text-danger" aria-hidden="true"></i> '.trans('general.no') !!}
|
{!! $license->reassignable ? '<i class="fas fa-check fa-fw text-success" aria-hidden="true"></i> '.trans('general.yes') : '<i class="fas fa-times fa-fw text-danger" aria-hidden="true"></i> '.trans('general.no') !!}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -378,8 +364,10 @@
|
||||||
|
|
||||||
</div> <!-- end row-striped -->
|
</div> <!-- end row-striped -->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</div> <!-- end tab-pane -->
|
|
||||||
|
</div>
|
||||||
|
</div> <!-- end tab-pane -->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -550,13 +538,100 @@
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div> <!-- /.col-md-12-->
|
</div> <!-- /.col-md-12-->
|
||||||
|
|
||||||
|
|
||||||
</div> <!-- /.row-->
|
</div> <!-- /.row-->
|
||||||
</div> <!-- /.tab-pane -->
|
</div> <!-- /.tab-pane -->
|
||||||
|
|
||||||
</div> <!-- /.tab-content -->
|
</div> <!-- /.tab-content -->
|
||||||
|
|
||||||
</div> <!-- nav-tabs-custom -->
|
</div> <!-- nav-tabs-custom -->
|
||||||
</div> <!-- /.col -->
|
</div> <!-- /.col -->
|
||||||
|
<div class="col-md-3">
|
||||||
|
|
||||||
|
@can('update', $license)
|
||||||
|
<a href="{{ route('licenses.edit', $license->id) }}" class="btn btn-block btn-primary" style="margin-bottom: 10px;">{{ trans('admin/licenses/general.edit') }}</a>
|
||||||
|
<a href="{{ route('clone/license', $license->id) }}" class="btn btn-block btn-primary" style="margin-bottom: 10px;">{{ trans('admin/licenses/general.clone') }}</a>
|
||||||
|
@endcan
|
||||||
|
|
||||||
|
@can('checkout', $license)
|
||||||
|
|
||||||
|
@if ($license->availCount()->count() > 0)
|
||||||
|
<a href="{{ route('licenses.checkout', $license->id) }}" class="btn-block btn bg-maroon" style="margin-bottom: 10px;">
|
||||||
|
{{ trans('general.checkout') }}
|
||||||
|
</a>
|
||||||
|
<a href="#" class="btn-block btn bg-maroon" style="margin-bottom: 10px;" data-toggle="modal" data-tooltip="true" title="{{ trans('admin/licenses/general.bulk.checkout_all.enabled_tooltip') }}" data-target="#checkoutFromAllModal">
|
||||||
|
{{ trans('admin/licenses/general.bulk.checkout_all.button') }}
|
||||||
|
</a>
|
||||||
|
|
||||||
|
@else
|
||||||
|
<a href="{{ route('licenses.checkout', $license->id) }}" class="btn btn-block bg-maroon disabled" style="margin-bottom: 10px;">
|
||||||
|
{{ trans('general.checkout') }}
|
||||||
|
</a>
|
||||||
|
<span data-tooltip="true" title=" {{ trans('admin/licenses/general.bulk.checkout_all.disabled_tooltip') }}">
|
||||||
|
<a href="#" class="btn btn-block bg-maroon disabled" style="margin-bottom: 10px;" data-tooltip="true" title="{{ trans('general.checkout') }}">
|
||||||
|
{{ trans('admin/licenses/general.bulk.checkout_all.button') }}
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
@endif
|
||||||
|
@endcan
|
||||||
|
|
||||||
|
@can('checkin', $license)
|
||||||
|
|
||||||
|
@if (($license->seats - $license->availCount()->count()) > 0 )
|
||||||
|
<a href="#" class="btn btn-block bg-purple" style="margin-bottom: 25px;" data-toggle="modal" data-tooltip="true" data-target="#checkinFromAllModal" data-content="{{ trans('general.sure_to_delete') }} data-title="{{ trans('general.delete') }}" onClick="return false;">
|
||||||
|
{{ trans('admin/licenses/general.bulk.checkin_all.button') }}
|
||||||
|
</a>
|
||||||
|
@else
|
||||||
|
<span data-tooltip="true" title=" {{ trans('admin/licenses/general.bulk.checkin_all.disabled_tooltip') }}">
|
||||||
|
<a href="#" class="btn btn-block bg-purple disabled" style="margin-bottom: 25px;">
|
||||||
|
{{ trans('admin/licenses/general.bulk.checkin_all.button') }}
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
@endif
|
||||||
|
@endcan
|
||||||
|
|
||||||
|
@can('delete', $license)
|
||||||
|
|
||||||
|
@if ($license->availCount()->count() == $license->seats)
|
||||||
|
<button class="btn btn-block btn-danger delete-asset" data-toggle="modal" data-title="{{ trans('general.delete') }}" data-content="{{ trans('general.delete_confirm', ['item' => $license->name]) }}" data-target="#dataConfirmModal">
|
||||||
|
{{ trans('general.delete') }}
|
||||||
|
</button>
|
||||||
|
@else
|
||||||
|
<span data-tooltip="true" title=" {{ trans('admin/licenses/general.delete_disabled') }}">
|
||||||
|
<a href="#" class="btn btn-block btn-danger disabled">
|
||||||
|
{{ trans('general.delete') }}
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
@endif
|
||||||
|
@endcan
|
||||||
|
</div>
|
||||||
|
|
||||||
</div> <!-- /.row -->
|
</div> <!-- /.row -->
|
||||||
|
|
||||||
|
|
||||||
|
@can('checkin', \App\Models\License::class)
|
||||||
|
@include ('modals.confirm-action',
|
||||||
|
[
|
||||||
|
'modal_name' => 'checkinFromAllModal',
|
||||||
|
'route' => route('licenses.bulkcheckin', $license->id),
|
||||||
|
'title' => trans('general.modal_confirm_generic'),
|
||||||
|
'body' => trans_choice('admin/licenses/general.bulk.checkin_all.modal', 2, ['checkedout_seats_count' => $checkedout_seats_count])
|
||||||
|
])
|
||||||
|
@endcan
|
||||||
|
|
||||||
|
@can('checkout', \App\Models\License::class)
|
||||||
|
@include ('modals.confirm-action',
|
||||||
|
[
|
||||||
|
'modal_name' => 'checkoutFromAllModal',
|
||||||
|
'route' => route('licenses.bulkcheckout', $license->id),
|
||||||
|
'title' => trans('general.modal_confirm_generic'),
|
||||||
|
'body' => trans_choice('admin/licenses/general.bulk.checkout_all.modal', 2, ['available_seats_count' => $available_seats_count])
|
||||||
|
])
|
||||||
|
@endcan
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@can('update', \App\Models\License::class)
|
@can('update', \App\Models\License::class)
|
||||||
@include ('modals.upload-file', ['item_type' => 'license', 'item_id' => $license->id])
|
@include ('modals.upload-file', ['item_type' => 'license', 'item_id' => $license->id])
|
||||||
@endcan
|
@endcan
|
||||||
|
@ -565,5 +640,15 @@
|
||||||
|
|
||||||
|
|
||||||
@section('moar_scripts')
|
@section('moar_scripts')
|
||||||
|
<script>
|
||||||
|
|
||||||
|
$('#dataConfirmModal').on('show.bs.modal', function (event) {
|
||||||
|
var content = $(event.relatedTarget).data('content');
|
||||||
|
var title = $(event.relatedTarget).data('title');
|
||||||
|
$(this).find(".modal-body").text(content);
|
||||||
|
$(this).find(".modal-header").text(title);
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
||||||
@include ('partials.bootstrap-table')
|
@include ('partials.bootstrap-table')
|
||||||
@stop
|
@stop
|
||||||
|
|
|
@ -30,6 +30,17 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Warranty Lookup URL -->
|
||||||
|
<div class="form-group {{ $errors->has('warranty_lookup_url') ? ' has-error' : '' }}">
|
||||||
|
<label for="support_url" class="col-md-3 control-label">{{ trans('admin/manufacturers/table.warranty_lookup_url') }}
|
||||||
|
</label>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<input class="form-control" type="text" name="warranty_lookup_url" id="warranty_lookup_url" value="{{ old('warranty_lookup_url', $item->warranty_lookup_url) }}" />
|
||||||
|
<p class="help-block">{!! trans('admin/manufacturers/message.support_url_help') !!}</p>
|
||||||
|
{!! $errors->first('warranty_lookup_url', '<span class="alert-msg" aria-hidden="true"><i class="fas fa-times" aria-hidden="true"></i> :message</span>') !!}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Support Phone -->
|
<!-- Support Phone -->
|
||||||
<div class="form-group {{ $errors->has('support_phone') ? ' has-error' : '' }}">
|
<div class="form-group {{ $errors->has('support_phone') ? ' has-error' : '' }}">
|
||||||
<label for="support_phone" class="col-md-3 control-label">{{ trans('admin/manufacturers/table.support_phone') }}
|
<label for="support_phone" class="col-md-3 control-label">{{ trans('admin/manufacturers/table.support_phone') }}
|
||||||
|
|
27
resources/views/modals/confirm-action.blade.php
Normal file
27
resources/views/modals/confirm-action.blade.php
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
<!-- Modal -->
|
||||||
|
<div class="modal fade" id="{{ $modal_name }}" tabindex="-1" role="dialog" aria-labelledby="{{ $modal_name }}Label" aria-hidden="true">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||||
|
<h4 class="modal-title" id="{{ $modal_name }}Label">{{ $title }}</h4>
|
||||||
|
</div>
|
||||||
|
<form action="{{ $route }}" method="POST" class="form-horizontal">
|
||||||
|
<input type="hidden" name="_token" value="{{ csrf_token() }}" />
|
||||||
|
<div class="modal-body">
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12">
|
||||||
|
{{ $body }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div> <!-- /.modal-body-->
|
||||||
|
<div class="modal-footer">
|
||||||
|
<a href="#" class="pull-left" data-dismiss="modal">{{ trans('button.cancel') }}</a>
|
||||||
|
<button type="submit" class="btn btn-primary">{{ trans('general.confirm') }}</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -4,7 +4,7 @@
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||||
<h2 class="modal-title" id="uploadFileModalLabel">{{ trans('general.file_upload') }}</h4>
|
<h4 class="modal-title" id="uploadFileModalLabel">{{ trans('general.file_upload') }}</h4>
|
||||||
</div>
|
</div>
|
||||||
{{ Form::open([
|
{{ Form::open([
|
||||||
'method' => 'POST',
|
'method' => 'POST',
|
||||||
|
|
|
@ -77,7 +77,7 @@
|
||||||
|
|
||||||
@if ($field->field_encrypted)
|
@if ($field->field_encrypted)
|
||||||
<div class="col-md-1 col-sm-1 text-left">
|
<div class="col-md-1 col-sm-1 text-left">
|
||||||
<i class="fas fa-lock" data-toggle="tooltip" data-placement="top" title="{{ trans('admin/custom_fields/general.value_encrypted') }}"></i>
|
<i class="fas fa-lock" data-tooltip="true" data-placement="top" title="{{ trans('admin/custom_fields/general.value_encrypted') }}"></i>
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
|
|
|
@ -94,7 +94,7 @@
|
||||||
|
|
||||||
exportTypes: ['xlsx', 'excel', 'csv', 'pdf','json', 'xml', 'txt', 'sql', 'doc' ],
|
exportTypes: ['xlsx', 'excel', 'csv', 'pdf','json', 'xml', 'txt', 'sql', 'doc' ],
|
||||||
onLoadSuccess: function () {
|
onLoadSuccess: function () {
|
||||||
$('[data-toggle="tooltip"]').tooltip(); // Needed to attach tooltips after ajax call
|
$('[data-tooltip="true"]').tooltip(); // Needed to attach tooltips after ajax call
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -215,7 +215,7 @@
|
||||||
text_help = '';
|
text_help = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
return '<nobr><a href="{{ config('app.url') }}/' + destination + '/' + value.id + '" data-toggle="tooltip" title="'+ status_meta[value.status_meta] + '"> <i class="fa ' + icon_style + ' text-' + text_color + '"></i> ' + value.name + ' ' + text_help + ' </a> </nobr>';
|
return '<nobr><a href="{{ config('app.url') }}/' + destination + '/' + value.id + '" data-tooltip="true" title="'+ status_meta[value.status_meta] + '"> <i class="fa ' + icon_style + ' text-' + text_color + '"></i> ' + value.name + ' ' + text_help + ' </a> </nobr>';
|
||||||
} else if ((value) && (value.name)) {
|
} else if ((value) && (value.name)) {
|
||||||
|
|
||||||
// Add some overrides for any funny urls we have
|
// Add some overrides for any funny urls we have
|
||||||
|
@ -269,21 +269,28 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((row.available_actions) && (row.available_actions.delete === true)) {
|
if ((row.available_actions) && (row.available_actions.delete === true)) {
|
||||||
|
|
||||||
|
// use the asset tag if no name is provided
|
||||||
|
var name_for_box = row.name
|
||||||
|
if (row.name=='') {
|
||||||
|
var name_for_box = row.asset_tag
|
||||||
|
}
|
||||||
|
|
||||||
actions += '<a href="{{ config('app.url') }}/' + dest + '/' + row.id + '" '
|
actions += '<a href="{{ config('app.url') }}/' + dest + '/' + row.id + '" '
|
||||||
+ ' class="btn btn-danger btn-sm delete-asset" data-toggle="tooltip" '
|
+ ' class="btn btn-danger btn-sm delete-asset" data-tooltip="true" '
|
||||||
+ ' data-toggle="modal" '
|
+ ' data-toggle="modal" '
|
||||||
+ ' data-content="{{ trans('general.sure_to_delete') }} ' + row.name + '?" '
|
+ ' data-content="{{ trans('general.sure_to_delete') }} ' + name_for_box + '?" '
|
||||||
+ ' data-title="{{ trans('general.delete') }}" onClick="return false;">'
|
+ ' data-title="{{ trans('general.delete') }}" onClick="return false;">'
|
||||||
+ '<i class="fas fa-trash" aria-hidden="true"></i><span class="sr-only">Delete</span></a> ';
|
+ '<i class="fas fa-trash" aria-hidden="true"></i><span class="sr-only">{{ trans('general.delete') }}</span></a> ';
|
||||||
} else {
|
} else {
|
||||||
actions += '<a class="btn btn-danger btn-sm delete-asset disabled" onClick="return false;"><i class="fas fa-trash"></i></a> ';
|
actions += '<span data-tooltip="true" title="{{ trans('general.cannot_be_deleted') }}"><a class="btn btn-danger btn-sm delete-asset disabled" onClick="return false;"><i class="fas fa-trash"></i></a></span> ';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if ((row.available_actions) && (row.available_actions.restore === true)) {
|
if ((row.available_actions) && (row.available_actions.restore === true)) {
|
||||||
actions += '<form style="display: inline;" method="POST" action="{{ config('app.url') }}/' + dest + '/' + row.id + '/restore"> ';
|
actions += '<form style="display: inline;" method="POST" action="{{ config('app.url') }}/' + dest + '/' + row.id + '/restore"> ';
|
||||||
actions += '@csrf';
|
actions += '@csrf';
|
||||||
actions += '<button class="btn btn-sm btn-warning" data-toggle="tooltip" title="{{ trans('general.restore') }}"><i class="fas fa-retweet"></i></button> ';
|
actions += '<button class="btn btn-sm btn-warning" data-tooltip="true" title="{{ trans('general.restore') }}"><i class="fas fa-retweet"></i></button> ';
|
||||||
}
|
}
|
||||||
|
|
||||||
actions +='</nobr>';
|
actions +='</nobr>';
|
||||||
|
@ -364,9 +371,9 @@
|
||||||
function licenseSeatInOutFormatter(value, row) {
|
function licenseSeatInOutFormatter(value, row) {
|
||||||
// The user is allowed to check the license seat out and it's available
|
// The user is allowed to check the license seat out and it's available
|
||||||
if ((row.available_actions.checkout == true) && (row.user_can_checkout == true) && ((!row.asset_id) && (!row.assigned_to))) {
|
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-toggle="tooltip" title="{{ trans('general.checkout_tooltip') }}">{{ trans('general.checkout') }}</a>';
|
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 {
|
} else {
|
||||||
return '<a href="{{ config('app.url') }}/licenses/' + row.id + '/checkin" class="btn btn-sm bg-purple" data-toggle="tooltip" 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="Check in this license seat.">{{ trans('general.checkin') }}</a>';
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -376,18 +383,26 @@
|
||||||
|
|
||||||
// The user is allowed to check items out, AND the item is deployable
|
// The user is allowed to check items out, AND the item is deployable
|
||||||
if ((row.available_actions.checkout == true) && (row.user_can_checkout == true) && ((!row.asset_id) && (!row.assigned_to))) {
|
if ((row.available_actions.checkout == true) && (row.user_can_checkout == true) && ((!row.asset_id) && (!row.assigned_to))) {
|
||||||
return '<a href="{{ config('app.url') }}/' + destination + '/' + row.id + '/checkout" class="btn btn-sm bg-maroon" data-toggle="tooltip" title="{{ trans('general.checkout_tooltip') }}">{{ trans('general.checkout') }}</a>';
|
|
||||||
|
|
||||||
// The user is allowed to check items out, but the item is not deployable
|
return '<a href="{{ config('app.url') }}/' + destination + '/' + row.id + '/checkout" class="btn btn-sm bg-maroon" data-tooltip="true" title="{{ trans('general.checkout_tooltip') }}">{{ trans('general.checkout') }}</a>';
|
||||||
|
|
||||||
|
// The user is allowed to check items out, but the item is not able to be checked out
|
||||||
} else if (((row.user_can_checkout == false)) && (row.available_actions.checkout == true) && (!row.assigned_to)) {
|
} else if (((row.user_can_checkout == false)) && (row.available_actions.checkout == true) && (!row.assigned_to)) {
|
||||||
return '<div data-toggle="tooltip" title="This item has a status label that is undeployable and cannot be checked out at this time."><a class="btn btn-sm bg-maroon disabled">{{ trans('general.checkout') }}</a></div>';
|
|
||||||
|
// We use slightly different language for assets versus other things, since they are the only
|
||||||
|
// item that has a status label
|
||||||
|
if (destination =='hardware') {
|
||||||
|
return '<span data-tooltip="true" title="{{ trans('admin/hardware/general.undeployable_tooltip') }}"><a class="btn btn-sm bg-maroon disabled">{{ trans('general.checkout') }}</a></span>';
|
||||||
|
} else {
|
||||||
|
return '<span data-tooltip="true" title="{{ trans('general.undeployable_tooltip') }}"><a class="btn btn-sm bg-maroon disabled">{{ trans('general.checkout') }}</a></span>';
|
||||||
|
}
|
||||||
|
|
||||||
// The user is allowed to check items in
|
// The user is allowed to check items in
|
||||||
} else if (row.available_actions.checkin == true) {
|
} else if (row.available_actions.checkin == true) {
|
||||||
if (row.assigned_to) {
|
if (row.assigned_to) {
|
||||||
return '<a href="{{ config('app.url') }}/' + destination + '/' + row.id + '/checkin" class="btn btn-sm bg-purple" data-toggle="tooltip" title="Check this item in so it is available for re-imaging, re-issue, etc.">{{ trans('general.checkin') }}</a>';
|
return '<a href="{{ config('app.url') }}/' + destination + '/' + row.id + '/checkin" class="btn btn-sm bg-purple" data-tooltip="true" title="Check this item in so it is available for re-imaging, re-issue, etc.">{{ trans('general.checkin') }}</a>';
|
||||||
} else if (row.assigned_pivot_id) {
|
} else if (row.assigned_pivot_id) {
|
||||||
return '<a href="{{ config('app.url') }}/' + destination + '/' + row.assigned_pivot_id + '/checkin" class="btn btn-sm bg-purple" data-toggle="tooltip" title="Check this item in so it is available for re-imaging, re-issue, etc.">{{ trans('general.checkin') }}</a>';
|
return '<a href="{{ config('app.url') }}/' + destination + '/' + row.assigned_pivot_id + '/checkin" class="btn btn-sm bg-purple" data-tooltip="true" title="Check this item in so it is available for re-imaging, re-issue, etc.">{{ trans('general.checkin') }}</a>';
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -401,11 +416,11 @@
|
||||||
// This is only used by the requestable assets section
|
// This is only used by the requestable assets section
|
||||||
function assetRequestActionsFormatter (row, value) {
|
function assetRequestActionsFormatter (row, value) {
|
||||||
if (value.assigned_to_self == true){
|
if (value.assigned_to_self == true){
|
||||||
return '<button class="btn btn-danger btn-sm disabled" data-toggle="tooltip" title="Cancel this item request">{{ trans('button.cancel') }}</button>';
|
return '<button class="btn btn-danger btn-sm disabled" data-tooltip="true" title="Cancel this item request">{{ trans('button.cancel') }}</button>';
|
||||||
} else if (value.available_actions.cancel == true) {
|
} else if (value.available_actions.cancel == true) {
|
||||||
return '<form action="{{ config('app.url') }}/account/request-asset/'+ value.id + '" method="POST">@csrf<button class="btn btn-danger btn-sm" data-toggle="tooltip" title="Cancel this item request">{{ trans('button.cancel') }}</button></form>';
|
return '<form action="{{ config('app.url') }}/account/request-asset/'+ value.id + '" method="POST">@csrf<button class="btn btn-danger btn-sm" data-tooltip="true" title="Cancel this item request">{{ trans('button.cancel') }}</button></form>';
|
||||||
} else if (value.available_actions.request == true) {
|
} else if (value.available_actions.request == true) {
|
||||||
return '<form action="{{ config('app.url') }}/account/request-asset/'+ value.id + '" method="POST">@csrf<button class="btn btn-primary btn-sm" data-toggle="tooltip" title="Request this item">{{ trans('button.request') }}</button></form>';
|
return '<form action="{{ config('app.url') }}/account/request-asset/'+ value.id + '" method="POST">@csrf<button class="btn btn-primary btn-sm" data-tooltip="true" title="Request this item">{{ trans('button.request') }}</button></form>';
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -496,8 +511,12 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function externalLinkFormatter(value) {
|
function externalLinkFormatter(value) {
|
||||||
|
|
||||||
if (value) {
|
if (value) {
|
||||||
return '<a href="' + value + '" target="_blank">' + value + '</a>';
|
if ((value.indexOf("{") === -1) || (value.indexOf("}") ===-1)) {
|
||||||
|
return '<i class="fa fa-external-link"></i> <a href="' + value + '" target="_blank">' + value + '</a>';
|
||||||
|
}
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -537,7 +556,7 @@
|
||||||
if ((row) && (row!=undefined)) {
|
if ((row) && (row!=undefined)) {
|
||||||
return '<a href="{{ config('app.url') }}/locations/' + row.id + '">' + row.name + '</a>';
|
return '<a href="{{ config('app.url') }}/locations/' + row.id + '">' + row.name + '</a>';
|
||||||
} else if (value.rtd_location) {
|
} else if (value.rtd_location) {
|
||||||
return '<a href="{{ config('app.url') }}/locations/' + value.rtd_location.id + '" data-toggle="tooltip" title="Default Location">' + value.rtd_location.name + '</a>';
|
return '<a href="{{ config('app.url') }}/locations/' + value.rtd_location.id + '" data-tooltip="true" title="Default Location">' + value.rtd_location.name + '</a>';
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -779,7 +798,7 @@
|
||||||
// This is necessary to make the bootstrap tooltips work inside of the
|
// This is necessary to make the bootstrap tooltips work inside of the
|
||||||
// wenzhixin/bootstrap-table formatters
|
// wenzhixin/bootstrap-table formatters
|
||||||
$('#table').on('post-body.bs.table', function () {
|
$('#table').on('post-body.bs.table', function () {
|
||||||
$('[data-toggle="tooltip"]').tooltip({
|
$('[data-tooltip="true"]').tooltip({
|
||||||
container: 'body'
|
container: 'body'
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<input class="form-control col-md-3" type="text" name="min_amt" id="min_amt" aria-label="min_amt" value="{{ old('min_amt', $item->min_amt) }}" />
|
<input class="form-control col-md-3" type="text" name="min_amt" id="min_amt" aria-label="min_amt" value="{{ old('min_amt', $item->min_amt) }}" />
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-7" style="margin-left: -15px;">
|
<div class="col-md-7" style="margin-left: -15px;">
|
||||||
<a href="#" data-toggle="tooltip" title="{{ trans('general.min_amt_help') }}"><i class="fas fa-info-circle" aria-hidden="true"></i>
|
<a href="#" data-tooltip="true" title="{{ trans('general.min_amt_help') }}"><i class="fas fa-info-circle" aria-hidden="true"></i>
|
||||||
<span class="sr-only">{{ trans('general.min_amt_help') }}</span>
|
<span class="sr-only">{{ trans('general.min_amt_help') }}</span>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<tbody class="permissions-group">
|
<tbody class="permissions-group">
|
||||||
<tr class="header-row permissions-row">
|
<tr class="header-row permissions-row">
|
||||||
<td class="col-md-5 tooltip-base permissions-item"
|
<td class="col-md-5 tooltip-base permissions-item"
|
||||||
data-toggle="tooltip"
|
data-tooltip="true"
|
||||||
data-placement="right"
|
data-placement="right"
|
||||||
title="{{ $localPermission['note'] }}"
|
title="{{ $localPermission['note'] }}"
|
||||||
>
|
>
|
||||||
|
@ -76,7 +76,7 @@
|
||||||
@if ($permission['display'])
|
@if ($permission['display'])
|
||||||
<td
|
<td
|
||||||
class="col-md-5 tooltip-base permissions-item"
|
class="col-md-5 tooltip-base permissions-item"
|
||||||
data-toggle="tooltip"
|
data-tooltip="true"
|
||||||
data-placement="right"
|
data-placement="right"
|
||||||
title="{{ $permission['note'] }}"
|
title="{{ $permission['note'] }}"
|
||||||
>
|
>
|
||||||
|
|
|
@ -499,6 +499,20 @@
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- LDAP Location -->
|
||||||
|
<div class="form-group {{ $errors->has('ldap_location') ? 'error' : '' }}">
|
||||||
|
<div class="col-md-3">
|
||||||
|
{{ Form::label('ldap_location', trans('admin/settings/general.ldap_location')) }}
|
||||||
|
</div>
|
||||||
|
<div class="col-md-9">
|
||||||
|
{{ Form::text('ldap_location', Request::old('ldap_location', $setting->ldap_location), ['class' => 'form-control','placeholder' => trans('general.example') .'physicaldeliveryofficename', $setting->demoMode]) }}
|
||||||
|
<p class="help-block">{!! trans('admin/settings/general.ldap_location_help') !!}</p>
|
||||||
|
{!! $errors->first('ldap_location', '<span class="alert-msg" aria-hidden="true">:message</span>') !!}
|
||||||
|
@if (config('app.lock_passwords')===true)
|
||||||
|
<p class="text-warning"><i class="fas fa-lock" aria-hidden="true"></i> {{ trans('general.feature_disabled') }}</p>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@if ($setting->ldap_enabled)
|
@if ($setting->ldap_enabled)
|
||||||
|
|
||||||
<!-- LDAP test -->
|
<!-- LDAP test -->
|
||||||
|
|
|
@ -119,6 +119,29 @@
|
||||||
</div>
|
</div>
|
||||||
</div> <!--/form-group-->
|
</div> <!--/form-group-->
|
||||||
|
|
||||||
|
<!-- activated -->
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-sm-3 control-label">
|
||||||
|
{{ trans('general.autoassign_licenses') }}
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
|
||||||
|
<label for="no_change_autoassign_licenses" class="form-control">
|
||||||
|
{{ Form::radio('autoassign_licenses', '', true, ['id' => 'no_change_autoassign_licenses', 'aria-label'=>'no_change_autoassign_licenses']) }}
|
||||||
|
{{ trans('general.do_not_change') }}
|
||||||
|
</label>
|
||||||
|
<label for="autoassign_licenses" class="form-control">
|
||||||
|
{{ Form::radio('autoassign_licenses', '1', old('autoassign_licenses'), ['id' => 'autoassign_licenses', 'aria-label'=>'autoassign_licenses']) }}
|
||||||
|
{{ trans('general.autoassign_licenses_help')}}
|
||||||
|
</label>
|
||||||
|
<label for="dont_autoassign_licenses" class="form-control">
|
||||||
|
{{ Form::radio('autoassign_licenses', '0', old('autoassign_licenses'), ['id' => 'dont_autoassign_licenses', 'aria-label'=>'dont_autoassign_licenses']) }}
|
||||||
|
{{ trans('general.no_autoassign_licenses_help')}}
|
||||||
|
</label>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div> <!--/form-group-->
|
||||||
|
|
||||||
<!-- activated -->
|
<!-- activated -->
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="col-sm-3 control-label">
|
<div class="col-sm-3 control-label">
|
||||||
|
|
|
@ -370,6 +370,20 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Auto assign checkbox -->
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-md-7 col-md-offset-3">
|
||||||
|
|
||||||
|
<label class="form-control" for="autoassign_licenses">
|
||||||
|
<input type="checkbox" value="1" name="autoassign_licenses" {{ (old('autoassign_licenses', $user->autoassign_licenses)) == '1' ? " checked='checked'" : '' }} aria-label="autoassign_licenses">
|
||||||
|
{{ trans('general.autoassign_licenses') }}
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<p class="help-block">{{ trans('general.autoassign_licenses_help_long') }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<!-- remote checkbox -->
|
<!-- remote checkbox -->
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
@ -383,15 +397,6 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Auto Assign checkbox -->
|
|
||||||
<div class="form-group">
|
|
||||||
<div class="col-md-7 col-md-offset-3">
|
|
||||||
<label for="autoassign_licenses" class="form-control">
|
|
||||||
<input type="checkbox" value="1" name="autoassign_licenses" {{ (old('autoassign_licenses', $user->autoassign_licenses)) == '1' ? ' checked="checked"' : '' }} aria-label="autoassign_licenses">
|
|
||||||
{{ trans('admin/users/general.auto_assign_label') }}
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Location -->
|
<!-- Location -->
|
||||||
@include ('partials.forms.edit.location-select', ['translated_name' => trans('general.location'), 'fieldname' => 'location_id'])
|
@include ('partials.forms.edit.location-select', ['translated_name' => trans('general.location'), 'fieldname' => 'location_id'])
|
||||||
|
@ -444,8 +449,8 @@
|
||||||
<!-- Country -->
|
<!-- Country -->
|
||||||
<div class="form-group{{ $errors->has('country') ? ' has-error' : '' }}">
|
<div class="form-group{{ $errors->has('country') ? ' has-error' : '' }}">
|
||||||
<label class="col-md-3 control-label" for="country">{{ trans('general.country') }}</label>
|
<label class="col-md-3 control-label" for="country">{{ trans('general.country') }}</label>
|
||||||
<div class="col-md-6">
|
<div class="col-md-9">
|
||||||
{!! Form::countries('country', old('country', $user->country), 'col-md-6 select2') !!}
|
{!! Form::countries('country', old('country', $user->country), 'col-md-12 select2') !!}
|
||||||
{!! $errors->first('country', '<span class="alert-msg" aria-hidden="true">:message</span>') !!}
|
{!! $errors->first('country', '<span class="alert-msg" aria-hidden="true">:message</span>') !!}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -122,7 +122,8 @@
|
||||||
@endcan
|
@endcan
|
||||||
|
|
||||||
@can('update', \App\Models\User::class)
|
@can('update', \App\Models\User::class)
|
||||||
<li class="pull-right"><a href="#" data-toggle="modal" data-target="#uploadFileModal">
|
<li class="pull-right">
|
||||||
|
<a href="#" data-toggle="modal" data-target="#uploadFileModal">
|
||||||
<span class="hidden-xs"><i class="fas fa-paperclip" aria-hidden="true"></i></span>
|
<span class="hidden-xs"><i class="fas fa-paperclip" aria-hidden="true"></i></span>
|
||||||
<span class="hidden-lg hidden-md hidden-xl"><i class="fas fa-paperclip fa-2x" aria-hidden="true"></i></span>
|
<span class="hidden-lg hidden-md hidden-xl"><i class="fas fa-paperclip fa-2x" aria-hidden="true"></i></span>
|
||||||
<span class="hidden-xs hidden-sm">{{ trans('button.upload') }}</span>
|
<span class="hidden-xs hidden-sm">{{ trans('button.upload') }}</span>
|
||||||
|
@ -519,23 +520,23 @@
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
<!-- login enabled -->
|
<!-- vip -->
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-3">
|
<div class="col-md-3">
|
||||||
{{ trans('admin/users/general.vip_label') }}
|
{{ trans('admin/users/general.vip_label') }}
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-9">
|
<div class="col-md-9">
|
||||||
{!! ($user->vip=='1') ? '<i class="fas fa-check text-success" aria-hidden="true"></i> '.trans('general.yes') : '<i class="fas fa-times text-danger" aria-hidden="true"></i> '.trans('general.no') !!}
|
{!! ($user->vip=='1') ? '<i class="fas fa-check fa-fw fa-fw text-success" aria-hidden="true"></i> '.trans('general.yes') : '<i class="fas fa-times fa-fw text-danger" aria-hidden="true"></i> '.trans('general.no') !!}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- login enabled -->
|
<!-- remote -->
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-3">
|
<div class="col-md-3">
|
||||||
{{ trans('admin/users/general.remote') }}
|
{{ trans('admin/users/general.remote') }}
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-9">
|
<div class="col-md-9">
|
||||||
{!! ($user->remote=='1') ? '<i class="fas fa-check text-success" aria-hidden="true"></i> '.trans('general.yes') : '<i class="fas fa-times text-danger" aria-hidden="true"></i> '.trans('general.no') !!}
|
{!! ($user->remote=='1') ? '<i class="fas fa-check fa-fw text-success" aria-hidden="true"></i> '.trans('general.yes') : '<i class="fas fa-times fa-fw text-danger" aria-hidden="true"></i> '.trans('general.no') !!}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -545,17 +546,28 @@
|
||||||
{{ trans('general.login_enabled') }}
|
{{ trans('general.login_enabled') }}
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-9">
|
<div class="col-md-9">
|
||||||
{!! ($user->activated=='1') ? '<i class="fas fa-check text-success" aria-hidden="true"></i> '.trans('general.yes') : '<i class="fas fa-times text-danger" aria-hidden="true"></i> '.trans('general.no') !!}
|
{!! ($user->activated=='1') ? '<i class="fas fa-check fa-fw text-success" aria-hidden="true"></i> '.trans('general.yes') : '<i class="fas fa-times fa-fw text-danger" aria-hidden="true"></i> '.trans('general.no') !!}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- LDAP -->
|
<!-- auto assign license -->
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-3">
|
||||||
|
{{ trans('general.autoassign_licenses') }}
|
||||||
|
</div>
|
||||||
|
<div class="col-md-9">
|
||||||
|
{!! ($user->autoassign_licenses=='1') ? '<i class="fas fa-check fa-fw text-success" aria-hidden="true"></i> '.trans('general.yes') : '<i class="fas fa-times fa-fw text-danger" aria-hidden="true"></i> '.trans('general.no') !!}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- LDAP -->
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-3">
|
<div class="col-md-3">
|
||||||
LDAP
|
LDAP
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-9">
|
<div class="col-md-9">
|
||||||
{!! ($user->ldap_import=='1') ? '<i class="fas fa-check text-success" aria-hidden="true"></i> '.trans('general.yes') : '<i class="fas fa-times text-danger" aria-hidden="true"></i> '.trans('general.no') !!}
|
{!! ($user->ldap_import=='1') ? '<i class="fas fa-check fa-fw text-success" aria-hidden="true"></i> '.trans('general.yes') : '<i class="fas fa-times fa-fw text-danger" aria-hidden="true"></i> '.trans('general.no') !!}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -569,7 +581,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-9">
|
<div class="col-md-9">
|
||||||
|
|
||||||
{!! ($user->two_factor_active()) ? '<i class="fas fa-check text-success" aria-hidden="true"></i> '.trans('general.yes') : '<i class="fas fa-times text-danger" aria-hidden="true"></i> '.trans('general.no') !!}
|
{!! ($user->two_factor_active()) ? '<i class="fas fa-check fa-fw text-success" aria-hidden="true"></i> '.trans('general.yes') : '<i class="fas fa-times fa-fw text-danger" aria-hidden="true"></i> '.trans('general.no') !!}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -580,7 +592,7 @@
|
||||||
{{ trans('admin/users/general.two_factor_enrolled') }}
|
{{ trans('admin/users/general.two_factor_enrolled') }}
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-9" id="two_factor_reset_toggle">
|
<div class="col-md-9" id="two_factor_reset_toggle">
|
||||||
{!! ($user->two_factor_active_and_enrolled()) ? '<i class="fas fa-check text-success" aria-hidden="true"></i> '.trans('general.yes') : '<i class="fas fa-times text-danger" aria-hidden="true"></i> '.trans('general.no') !!}
|
{!! ($user->two_factor_active_and_enrolled()) ? '<i class="fas fa-check fa-fw text-success" aria-hidden="true"></i> '.trans('general.yes') : '<i class="fas fa-times fa-fw text-danger" aria-hidden="true"></i> '.trans('general.no') !!}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -592,9 +604,9 @@
|
||||||
<div class="col-md-3">
|
<div class="col-md-3">
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-9" style="margin-top: 10px;">
|
<div class="col-md-9">
|
||||||
|
|
||||||
<a class="btn btn-default btn-sm pull-left" id="two_factor_reset" style="margin-right: 10px;">
|
<a class="btn btn-default btn-sm" id="two_factor_reset" style="margin-right: 10px; margin-top: 10px;">
|
||||||
{{ trans('admin/settings/general.two_factor_reset') }}
|
{{ trans('admin/settings/general.two_factor_reset') }}
|
||||||
</a>
|
</a>
|
||||||
<span id="two_factor_reseticon">
|
<span id="two_factor_reseticon">
|
||||||
|
@ -1031,9 +1043,9 @@ $(function () {
|
||||||
dataType: 'json',
|
dataType: 'json',
|
||||||
|
|
||||||
success: function (data) {
|
success: function (data) {
|
||||||
$("#two_factor_reset_toggle").html('').html('<i class="fas fa-times text-danger" aria-hidden="true"></i> {{ trans('general.no') }}');
|
$("#two_factor_reset_toggle").html('').html('<span class="text-danger"><i class="fas fa-times" aria-hidden="true"></i> {{ trans('general.no') }}</span>');
|
||||||
$("#two_factor_reseticon").html('');
|
$("#two_factor_reseticon").html('');
|
||||||
$("#two_factor_resetstatus").html('<i class="fas fa-check text-success"></i>' + data.message);
|
$("#two_factor_resetstatus").html('<span class="text-success"><i class="fas fa-check"></i> ' + data.message + '</span>');
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@ Route::group(['middleware' => 'auth'], function () {
|
||||||
|
|
||||||
Route::get('{locationId}/clone',
|
Route::get('{locationId}/clone',
|
||||||
[LocationsController::class, 'getClone']
|
[LocationsController::class, 'getClone']
|
||||||
)->name('clone/license');
|
)->name('clone/location');
|
||||||
|
|
||||||
Route::get(
|
Route::get(
|
||||||
'{locationId}/printassigned',
|
'{locationId}/printassigned',
|
||||||
|
|
|
@ -25,10 +25,21 @@ Route::group(['prefix' => 'licenses', 'middleware' => ['auth']], function () {
|
||||||
[Licenses\LicenseCheckinController::class, 'store']
|
[Licenses\LicenseCheckinController::class, 'store']
|
||||||
)->name('licenses.checkin.save');
|
)->name('licenses.checkin.save');
|
||||||
|
|
||||||
|
Route::post(
|
||||||
|
'{licenseId}/bulkcheckin',
|
||||||
|
[Licenses\LicenseCheckinController::class, 'bulkCheckin']
|
||||||
|
)->name('licenses.bulkcheckin');
|
||||||
|
|
||||||
|
Route::post(
|
||||||
|
'{licenseId}/bulkcheckout',
|
||||||
|
[Licenses\LicenseCheckoutController::class, 'bulkCheckout']
|
||||||
|
)->name('licenses.bulkcheckout');
|
||||||
|
|
||||||
Route::post(
|
Route::post(
|
||||||
'{licenseId}/upload',
|
'{licenseId}/upload',
|
||||||
[Licenses\LicenseFilesController::class, 'store']
|
[Licenses\LicenseFilesController::class, 'store']
|
||||||
)->name('upload/license');
|
)->name('upload/license');
|
||||||
|
|
||||||
Route::delete(
|
Route::delete(
|
||||||
'{licenseId}/deletefile/{fileId}',
|
'{licenseId}/deletefile/{fileId}',
|
||||||
[Licenses\LicenseFilesController::class, 'destroy']
|
[Licenses\LicenseFilesController::class, 'destroy']
|
||||||
|
|
96
tests/Feature/Notifications/AccessoryWebhookTest.php
Normal file
96
tests/Feature/Notifications/AccessoryWebhookTest.php
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Tests\Feature\Notifications;
|
||||||
|
|
||||||
|
use App\Events\CheckoutableCheckedIn;
|
||||||
|
use App\Events\CheckoutableCheckedOut;
|
||||||
|
use App\Models\Accessory;
|
||||||
|
use App\Models\Setting;
|
||||||
|
use App\Models\User;
|
||||||
|
use App\Notifications\CheckinAccessoryNotification;
|
||||||
|
use App\Notifications\CheckoutAccessoryNotification;
|
||||||
|
use Illuminate\Notifications\AnonymousNotifiable;
|
||||||
|
use Illuminate\Support\Facades\Notification;
|
||||||
|
use Tests\Support\InteractsWithSettings;
|
||||||
|
use Tests\TestCase;
|
||||||
|
|
||||||
|
class AccessoryWebhookTest extends TestCase
|
||||||
|
{
|
||||||
|
use InteractsWithSettings;
|
||||||
|
|
||||||
|
public function testAccessoryCheckoutSendsWebhookNotificationWhenSettingEnabled()
|
||||||
|
{
|
||||||
|
Notification::fake();
|
||||||
|
|
||||||
|
$this->settings->enableWebhook();
|
||||||
|
|
||||||
|
event(new CheckoutableCheckedOut(
|
||||||
|
Accessory::factory()->appleBtKeyboard()->create(),
|
||||||
|
User::factory()->create(),
|
||||||
|
User::factory()->superuser()->create(),
|
||||||
|
''
|
||||||
|
));
|
||||||
|
|
||||||
|
Notification::assertSentTo(
|
||||||
|
new AnonymousNotifiable,
|
||||||
|
CheckoutAccessoryNotification::class,
|
||||||
|
function ($notification, $channels, $notifiable) {
|
||||||
|
return $notifiable->routes['slack'] === Setting::getSettings()->webhook_endpoint;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testAccessoryCheckoutDoesNotSendWebhookNotificationWhenSettingDisabled()
|
||||||
|
{
|
||||||
|
Notification::fake();
|
||||||
|
|
||||||
|
$this->settings->disableWebhook();
|
||||||
|
|
||||||
|
event(new CheckoutableCheckedOut(
|
||||||
|
Accessory::factory()->appleBtKeyboard()->create(),
|
||||||
|
User::factory()->create(),
|
||||||
|
User::factory()->superuser()->create(),
|
||||||
|
''
|
||||||
|
));
|
||||||
|
|
||||||
|
Notification::assertNotSentTo(new AnonymousNotifiable, CheckoutAccessoryNotification::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testAccessoryCheckinSendsWebhookNotificationWhenSettingEnabled()
|
||||||
|
{
|
||||||
|
Notification::fake();
|
||||||
|
|
||||||
|
$this->settings->enableWebhook();
|
||||||
|
|
||||||
|
event(new CheckoutableCheckedIn(
|
||||||
|
Accessory::factory()->appleBtKeyboard()->create(),
|
||||||
|
User::factory()->create(),
|
||||||
|
User::factory()->superuser()->create(),
|
||||||
|
''
|
||||||
|
));
|
||||||
|
|
||||||
|
Notification::assertSentTo(
|
||||||
|
new AnonymousNotifiable,
|
||||||
|
CheckinAccessoryNotification::class,
|
||||||
|
function ($notification, $channels, $notifiable) {
|
||||||
|
return $notifiable->routes['slack'] === Setting::getSettings()->webhook_endpoint;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testAccessoryCheckinDoesNotSendWebhookNotificationWhenSettingDisabled()
|
||||||
|
{
|
||||||
|
Notification::fake();
|
||||||
|
|
||||||
|
$this->settings->disableWebhook();
|
||||||
|
|
||||||
|
event(new CheckoutableCheckedIn(
|
||||||
|
Accessory::factory()->appleBtKeyboard()->create(),
|
||||||
|
User::factory()->create(),
|
||||||
|
User::factory()->superuser()->create(),
|
||||||
|
''
|
||||||
|
));
|
||||||
|
|
||||||
|
Notification::assertNotSentTo(new AnonymousNotifiable, CheckinAccessoryNotification::class);
|
||||||
|
}
|
||||||
|
}
|
115
tests/Feature/Notifications/AssetWebhookTest.php
Normal file
115
tests/Feature/Notifications/AssetWebhookTest.php
Normal file
|
@ -0,0 +1,115 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Tests\Feature\Notifications;
|
||||||
|
|
||||||
|
use App\Events\CheckoutableCheckedIn;
|
||||||
|
use App\Events\CheckoutableCheckedOut;
|
||||||
|
use App\Models\Asset;
|
||||||
|
use App\Models\Location;
|
||||||
|
use App\Models\Setting;
|
||||||
|
use App\Models\User;
|
||||||
|
use App\Notifications\CheckinAssetNotification;
|
||||||
|
use App\Notifications\CheckoutAssetNotification;
|
||||||
|
use Illuminate\Notifications\AnonymousNotifiable;
|
||||||
|
use Illuminate\Support\Facades\Notification;
|
||||||
|
use Tests\Support\InteractsWithSettings;
|
||||||
|
use Tests\TestCase;
|
||||||
|
|
||||||
|
class AssetWebhookTest extends TestCase
|
||||||
|
{
|
||||||
|
use InteractsWithSettings;
|
||||||
|
|
||||||
|
public function targets(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'Asset checked out to user' => [fn() => User::factory()->create()],
|
||||||
|
'Asset checked out to asset' => [fn() => $this->createAsset()],
|
||||||
|
'Asset checked out to location' => [fn() => Location::factory()->create()],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @dataProvider targets */
|
||||||
|
public function testAssetCheckoutSendsWebhookNotificationWhenSettingEnabled($checkoutTarget)
|
||||||
|
{
|
||||||
|
Notification::fake();
|
||||||
|
|
||||||
|
$this->settings->enableWebhook();
|
||||||
|
|
||||||
|
event(new CheckoutableCheckedOut(
|
||||||
|
$this->createAsset(),
|
||||||
|
$checkoutTarget(),
|
||||||
|
User::factory()->superuser()->create(),
|
||||||
|
''
|
||||||
|
));
|
||||||
|
|
||||||
|
Notification::assertSentTo(
|
||||||
|
new AnonymousNotifiable,
|
||||||
|
CheckoutAssetNotification::class,
|
||||||
|
function ($notification, $channels, $notifiable) {
|
||||||
|
return $notifiable->routes['slack'] === Setting::getSettings()->webhook_endpoint;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @dataProvider targets */
|
||||||
|
public function testAssetCheckoutDoesNotSendWebhookNotificationWhenSettingDisabled($checkoutTarget)
|
||||||
|
{
|
||||||
|
Notification::fake();
|
||||||
|
|
||||||
|
$this->settings->disableWebhook();
|
||||||
|
|
||||||
|
event(new CheckoutableCheckedOut(
|
||||||
|
$this->createAsset(),
|
||||||
|
$checkoutTarget(),
|
||||||
|
User::factory()->superuser()->create(),
|
||||||
|
''
|
||||||
|
));
|
||||||
|
|
||||||
|
Notification::assertNotSentTo(new AnonymousNotifiable, CheckoutAssetNotification::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @dataProvider targets */
|
||||||
|
public function testAssetCheckinSendsWebhookNotificationWhenSettingEnabled($checkoutTarget)
|
||||||
|
{
|
||||||
|
Notification::fake();
|
||||||
|
|
||||||
|
$this->settings->enableWebhook();
|
||||||
|
|
||||||
|
event(new CheckoutableCheckedIn(
|
||||||
|
$this->createAsset(),
|
||||||
|
$checkoutTarget(),
|
||||||
|
User::factory()->superuser()->create(),
|
||||||
|
''
|
||||||
|
));
|
||||||
|
|
||||||
|
Notification::assertSentTo(
|
||||||
|
new AnonymousNotifiable,
|
||||||
|
CheckinAssetNotification::class,
|
||||||
|
function ($notification, $channels, $notifiable) {
|
||||||
|
return $notifiable->routes['slack'] === Setting::getSettings()->webhook_endpoint;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @dataProvider targets */
|
||||||
|
public function testAssetCheckinDoesNotSendWebhookNotificationWhenSettingDisabled($checkoutTarget)
|
||||||
|
{
|
||||||
|
Notification::fake();
|
||||||
|
|
||||||
|
$this->settings->disableWebhook();
|
||||||
|
|
||||||
|
event(new CheckoutableCheckedIn(
|
||||||
|
$this->createAsset(),
|
||||||
|
$checkoutTarget(),
|
||||||
|
User::factory()->superuser()->create(),
|
||||||
|
''
|
||||||
|
));
|
||||||
|
|
||||||
|
Notification::assertNotSentTo(new AnonymousNotifiable, CheckinAssetNotification::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function createAsset()
|
||||||
|
{
|
||||||
|
return Asset::factory()->laptopMbp()->create();
|
||||||
|
}
|
||||||
|
}
|
50
tests/Feature/Notifications/ComponentWebhookTest.php
Normal file
50
tests/Feature/Notifications/ComponentWebhookTest.php
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Tests\Feature\Notifications;
|
||||||
|
|
||||||
|
use App\Events\CheckoutableCheckedIn;
|
||||||
|
use App\Events\CheckoutableCheckedOut;
|
||||||
|
use App\Models\Asset;
|
||||||
|
use App\Models\Component;
|
||||||
|
use App\Models\User;
|
||||||
|
use Illuminate\Support\Facades\Notification;
|
||||||
|
use Tests\Support\InteractsWithSettings;
|
||||||
|
use Tests\TestCase;
|
||||||
|
|
||||||
|
class ComponentWebhookTest extends TestCase
|
||||||
|
{
|
||||||
|
|
||||||
|
use InteractsWithSettings;
|
||||||
|
|
||||||
|
public function testComponentCheckoutDoesNotSendWebhookNotification()
|
||||||
|
{
|
||||||
|
Notification::fake();
|
||||||
|
|
||||||
|
$this->settings->enableWebhook();
|
||||||
|
|
||||||
|
event(new CheckoutableCheckedOut(
|
||||||
|
Component::factory()->ramCrucial8()->create(),
|
||||||
|
Asset::factory()->laptopMbp()->create(),
|
||||||
|
User::factory()->superuser()->create(),
|
||||||
|
''
|
||||||
|
));
|
||||||
|
|
||||||
|
Notification::assertNothingSent();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testComponentCheckinDoesNotSendWebhookNotification()
|
||||||
|
{
|
||||||
|
Notification::fake();
|
||||||
|
|
||||||
|
$this->settings->enableWebhook();
|
||||||
|
|
||||||
|
event(new CheckoutableCheckedIn(
|
||||||
|
Component::factory()->ramCrucial8()->create(),
|
||||||
|
Asset::factory()->laptopMbp()->create(),
|
||||||
|
User::factory()->superuser()->create(),
|
||||||
|
''
|
||||||
|
));
|
||||||
|
|
||||||
|
Notification::assertNothingSent();
|
||||||
|
}
|
||||||
|
}
|
56
tests/Feature/Notifications/ConsumableWebhookTest.php
Normal file
56
tests/Feature/Notifications/ConsumableWebhookTest.php
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Tests\Feature\Notifications;
|
||||||
|
|
||||||
|
use App\Events\CheckoutableCheckedOut;
|
||||||
|
use App\Models\Consumable;
|
||||||
|
use App\Models\Setting;
|
||||||
|
use App\Models\User;
|
||||||
|
use App\Notifications\CheckoutConsumableNotification;
|
||||||
|
use Illuminate\Notifications\AnonymousNotifiable;
|
||||||
|
use Illuminate\Support\Facades\Notification;
|
||||||
|
use Tests\Support\InteractsWithSettings;
|
||||||
|
use Tests\TestCase;
|
||||||
|
|
||||||
|
class ConsumableWebhookTest extends TestCase
|
||||||
|
{
|
||||||
|
use InteractsWithSettings;
|
||||||
|
|
||||||
|
public function testConsumableCheckoutSendsWebhookNotificationWhenSettingEnabled()
|
||||||
|
{
|
||||||
|
Notification::fake();
|
||||||
|
|
||||||
|
$this->settings->enableWebhook();
|
||||||
|
|
||||||
|
event(new CheckoutableCheckedOut(
|
||||||
|
Consumable::factory()->cardstock()->create(),
|
||||||
|
User::factory()->create(),
|
||||||
|
User::factory()->superuser()->create(),
|
||||||
|
''
|
||||||
|
));
|
||||||
|
|
||||||
|
Notification::assertSentTo(
|
||||||
|
new AnonymousNotifiable,
|
||||||
|
CheckoutConsumableNotification::class,
|
||||||
|
function ($notification, $channels, $notifiable) {
|
||||||
|
return $notifiable->routes['slack'] === Setting::getSettings()->webhook_endpoint;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testConsumableCheckoutDoesNotSendWebhookNotificationWhenSettingDisabled()
|
||||||
|
{
|
||||||
|
Notification::fake();
|
||||||
|
|
||||||
|
$this->settings->disableWebhook();
|
||||||
|
|
||||||
|
event(new CheckoutableCheckedOut(
|
||||||
|
Consumable::factory()->cardstock()->create(),
|
||||||
|
User::factory()->create(),
|
||||||
|
User::factory()->superuser()->create(),
|
||||||
|
''
|
||||||
|
));
|
||||||
|
|
||||||
|
Notification::assertNotSentTo(new AnonymousNotifiable, CheckoutConsumableNotification::class);
|
||||||
|
}
|
||||||
|
}
|
109
tests/Feature/Notifications/LicenseWebhookTest.php
Normal file
109
tests/Feature/Notifications/LicenseWebhookTest.php
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Tests\Feature\Notifications;
|
||||||
|
|
||||||
|
use App\Events\CheckoutableCheckedIn;
|
||||||
|
use App\Events\CheckoutableCheckedOut;
|
||||||
|
use App\Models\Asset;
|
||||||
|
use App\Models\LicenseSeat;
|
||||||
|
use App\Models\Setting;
|
||||||
|
use App\Models\User;
|
||||||
|
use App\Notifications\CheckinLicenseSeatNotification;
|
||||||
|
use App\Notifications\CheckoutLicenseSeatNotification;
|
||||||
|
use Illuminate\Notifications\AnonymousNotifiable;
|
||||||
|
use Illuminate\Support\Facades\Notification;
|
||||||
|
use Tests\Support\InteractsWithSettings;
|
||||||
|
use Tests\TestCase;
|
||||||
|
|
||||||
|
class LicenseWebhookTest extends TestCase
|
||||||
|
{
|
||||||
|
use InteractsWithSettings;
|
||||||
|
|
||||||
|
public function targets(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'License checked out to user' => [fn() => User::factory()->create()],
|
||||||
|
'License checked out to asset' => [fn() => Asset::factory()->laptopMbp()->create()],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @dataProvider targets */
|
||||||
|
public function testLicenseCheckoutSendsWebhookNotificationWhenSettingEnabled($checkoutTarget)
|
||||||
|
{
|
||||||
|
Notification::fake();
|
||||||
|
|
||||||
|
$this->settings->enableWebhook();
|
||||||
|
|
||||||
|
event(new CheckoutableCheckedOut(
|
||||||
|
LicenseSeat::factory()->create(),
|
||||||
|
$checkoutTarget(),
|
||||||
|
User::factory()->superuser()->create(),
|
||||||
|
''
|
||||||
|
));
|
||||||
|
|
||||||
|
Notification::assertSentTo(
|
||||||
|
new AnonymousNotifiable,
|
||||||
|
CheckoutLicenseSeatNotification::class,
|
||||||
|
function ($notification, $channels, $notifiable) {
|
||||||
|
return $notifiable->routes['slack'] === Setting::getSettings()->webhook_endpoint;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @dataProvider targets */
|
||||||
|
public function testLicenseCheckoutDoesNotSendWebhookNotificationWhenSettingDisabled($checkoutTarget)
|
||||||
|
{
|
||||||
|
Notification::fake();
|
||||||
|
|
||||||
|
$this->settings->disableWebhook();
|
||||||
|
|
||||||
|
event(new CheckoutableCheckedOut(
|
||||||
|
LicenseSeat::factory()->create(),
|
||||||
|
$checkoutTarget(),
|
||||||
|
User::factory()->superuser()->create(),
|
||||||
|
''
|
||||||
|
));
|
||||||
|
|
||||||
|
Notification::assertNotSentTo(new AnonymousNotifiable, CheckoutLicenseSeatNotification::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @dataProvider targets */
|
||||||
|
public function testLicenseCheckinSendsWebhookNotificationWhenSettingEnabled($checkoutTarget)
|
||||||
|
{
|
||||||
|
Notification::fake();
|
||||||
|
|
||||||
|
$this->settings->enableWebhook();
|
||||||
|
|
||||||
|
event(new CheckoutableCheckedIn(
|
||||||
|
LicenseSeat::factory()->create(),
|
||||||
|
$checkoutTarget(),
|
||||||
|
User::factory()->superuser()->create(),
|
||||||
|
''
|
||||||
|
));
|
||||||
|
|
||||||
|
Notification::assertSentTo(
|
||||||
|
new AnonymousNotifiable,
|
||||||
|
CheckinLicenseSeatNotification::class,
|
||||||
|
function ($notification, $channels, $notifiable) {
|
||||||
|
return $notifiable->routes['slack'] === Setting::getSettings()->webhook_endpoint;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @dataProvider targets */
|
||||||
|
public function testLicenseCheckinDoesNotSendWebhookNotificationWhenSettingDisabled($checkoutTarget)
|
||||||
|
{
|
||||||
|
Notification::fake();
|
||||||
|
|
||||||
|
$this->settings->disableWebhook();
|
||||||
|
|
||||||
|
event(new CheckoutableCheckedIn(
|
||||||
|
LicenseSeat::factory()->create(),
|
||||||
|
$checkoutTarget(),
|
||||||
|
User::factory()->superuser()->create(),
|
||||||
|
''
|
||||||
|
));
|
||||||
|
|
||||||
|
Notification::assertNotSentTo(new AnonymousNotifiable, CheckinLicenseSeatNotification::class);
|
||||||
|
}
|
||||||
|
}
|
61
tests/Feature/Users/UpdateUserTest.php
Normal file
61
tests/Feature/Users/UpdateUserTest.php
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Tests\Feature\Users;
|
||||||
|
|
||||||
|
use App\Models\User;
|
||||||
|
use Tests\Support\InteractsWithSettings;
|
||||||
|
use Tests\TestCase;
|
||||||
|
|
||||||
|
class UpdateUserTest extends TestCase
|
||||||
|
{
|
||||||
|
use InteractsWithSettings;
|
||||||
|
|
||||||
|
public function testUsersCanBeActivated()
|
||||||
|
{
|
||||||
|
$admin = User::factory()->superuser()->create();
|
||||||
|
$user = User::factory()->create(['activated' => false]);
|
||||||
|
|
||||||
|
$this->actingAs($admin)
|
||||||
|
->put(route('users.update', $user), [
|
||||||
|
'first_name' => $user->first_name,
|
||||||
|
'username' => $user->username,
|
||||||
|
'activated' => 1,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->assertTrue($user->refresh()->activated);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testUsersCanBeDeactivated()
|
||||||
|
{
|
||||||
|
$admin = User::factory()->superuser()->create();
|
||||||
|
$user = User::factory()->create(['activated' => true]);
|
||||||
|
|
||||||
|
$this->actingAs($admin)
|
||||||
|
->put(route('users.update', $user), [
|
||||||
|
'first_name' => $user->first_name,
|
||||||
|
'username' => $user->username,
|
||||||
|
// checkboxes that are not checked are
|
||||||
|
// not included in the request payload
|
||||||
|
// 'activated' => 0,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->assertFalse($user->refresh()->activated);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testUsersUpdatingThemselvesDoNotDeactivateTheirAccount()
|
||||||
|
{
|
||||||
|
$admin = User::factory()->superuser()->create(['activated' => true]);
|
||||||
|
|
||||||
|
$this->actingAs($admin)
|
||||||
|
->put(route('users.update', $admin), [
|
||||||
|
'first_name' => $admin->first_name,
|
||||||
|
'username' => $admin->username,
|
||||||
|
// checkboxes that are disabled are not
|
||||||
|
// included in the request payload
|
||||||
|
// even if they are checked
|
||||||
|
// 'activated' => 0,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->assertTrue($admin->refresh()->activated);
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,6 +23,24 @@ class Settings
|
||||||
return $this->update(['full_multiple_companies_support' => 1]);
|
return $this->update(['full_multiple_companies_support' => 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function enableWebhook(): Settings
|
||||||
|
{
|
||||||
|
return $this->update([
|
||||||
|
'webhook_botname' => 'SnipeBot5000',
|
||||||
|
'webhook_endpoint' => 'https://hooks.slack.com/services/NZ59/Q446/672N',
|
||||||
|
'webhook_channel' => '#it',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function disableWebhook(): Settings
|
||||||
|
{
|
||||||
|
return $this->update([
|
||||||
|
'webhook_botname' => '',
|
||||||
|
'webhook_endpoint' => '',
|
||||||
|
'webhook_channel' => '',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array $attributes Attributes to modify in the application's settings.
|
* @param array $attributes Attributes to modify in the application's settings.
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in a new issue