Compare commits
273 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5979a18852 | |||
| 5efb803b60 | |||
| fd4a8edae9 | |||
| e9fdf06bf6 | |||
| 0a5b72e71e | |||
| 51168e8e10 | |||
| cefdca3d22 | |||
| cc5eee1890 | |||
| d3864db5e1 | |||
| ece8ae3adc | |||
| e25829c759 | |||
| 92afd5f232 | |||
| b934d2e504 | |||
| 8cf70e7e20 | |||
| cdfd720c65 | |||
| c0f791cf13 | |||
| 290cf79778 | |||
| 8af1481749 | |||
| d8f404096c | |||
| ea2f7617df | |||
| b6c258bb12 | |||
| 804b49cefb | |||
| 305b0d8edb | |||
| 05996019e5 | |||
| 31a967e072 | |||
| 0b56ebf291 | |||
| fcc87b3219 | |||
| 82fca0c72d | |||
| 51661b0a21 | |||
| e8670fe591 | |||
| bee1dfc4a6 | |||
| 83c8449aca | |||
| 9dba1bb3e5 | |||
| 76e3398d44 | |||
| a7e12931fa | |||
| ba04c64567 | |||
| 8c8352ecc6 | |||
| 64b670033d | |||
| b9d102a5fb | |||
| 77076e02e8 | |||
| c6a761a5ad | |||
| 6f3a90c48b | |||
| 8f160a8590 | |||
| 2278d5bfd8 | |||
| 66ac147c9e | |||
| 05e0d15ae4 | |||
| 8562f018ed | |||
| 0cbdcce3ea | |||
| 980be65193 | |||
| 3aaaea37e4 | |||
| 964c594c4c | |||
| 9430c4bf43 | |||
| 538757317b | |||
| fe986f7c51 | |||
| 09105871d9 | |||
| e84a6059f4 | |||
| 09f20873df | |||
| 2adc1e8ba9 | |||
| 4a6c18532b | |||
| 921f882680 | |||
| f79e5add58 | |||
| d98d06377e | |||
| 22fdd05314 | |||
| 8c15a4e0c6 | |||
| 9250b45e6e | |||
| 3a1de3d2a5 | |||
| b59dd11304 | |||
| b6222abb7c | |||
| dcf8e4f5ef | |||
| f195073ac3 | |||
| 452a9d6725 | |||
| 1d74ddc547 | |||
| 932b589a14 | |||
| 671e514785 | |||
| 1e2ebdb69c | |||
| 148751d927 | |||
| efecdfaea0 | |||
| ab9c84a6b6 | |||
| 8711bc0dbd | |||
| 0adebd1ec8 | |||
| 43c1e893c0 | |||
| 7ce63e653b | |||
| e5129a8b98 | |||
| a922c1a298 | |||
| f4aa812d96 | |||
| 0c9e41e1fa | |||
| 1d6320a88f | |||
| 4696e799ed | |||
| 2e08a91c53 | |||
| 4fd35573ad | |||
| caf2cdbf6f | |||
| c0293a7c1c | |||
| 17405f5de1 | |||
| bfefa10462 | |||
| 55a140045b | |||
| 897bd2c56e | |||
| 7321c5937f | |||
| 98700cab8b | |||
| 3d07635820 | |||
| 59b18a6ada | |||
| ce525c1985 | |||
| a0d163a3c4 | |||
| faab971931 | |||
| 38eb16dfea | |||
| 4494456cad | |||
| 876dde1280 | |||
| 17ee904828 | |||
| 4f1b58cd35 | |||
| edcd3afc3e | |||
| e433b0f9d8 | |||
| f137e516a6 | |||
| ba38b841cb | |||
| f7c6697a69 | |||
| 498fc3762d | |||
| eb24eb1fff | |||
| 3e5e6ba99a | |||
| 0396267388 | |||
| 4577ba39d7 | |||
| 7eef1b4bcf | |||
| 578da128e9 | |||
| bb4d49690f | |||
| 7eb94d16a1 | |||
| 65bd33c274 | |||
| 0f7aa21a59 | |||
| ee0814716a | |||
| f56e1768b6 | |||
| 012afe99e2 | |||
| 0c02b6d24e | |||
| 2f34336f2b | |||
| afe6f43a1b | |||
| 738e33b165 | |||
| 566fd4d2e1 | |||
| c61887da21 | |||
| 6852b74317 | |||
| 4c266fdcf4 | |||
| c26a2f8291 | |||
| a994e54726 | |||
| 172c7c75a8 | |||
| 487fd17ce3 | |||
| 65353fa422 | |||
| 4f4920615c | |||
| c162c02304 | |||
| 1bb1480f67 | |||
| 8dceacc2b4 | |||
| ffae537400 | |||
| 5ce7882bf5 | |||
| b36594f508 | |||
| 59c9c22a59 | |||
| 9097681c13 | |||
| 567f741d95 | |||
| 9b1fb90519 | |||
| b567ffdcfe | |||
| 9d44607b8f | |||
| 35ee52212f | |||
| e9e32fdb00 | |||
| 6c130ce8ac | |||
| dd7db0de93 | |||
| 70efac8fa7 | |||
| 6e2556eefd | |||
| fb6a545cc6 | |||
| e5c1e41966 | |||
| 61617a2629 | |||
| a3e80882c1 | |||
| 31980c55de | |||
| d1022e8ff7 | |||
| e6ff447ee8 | |||
| 1123272ae8 | |||
| 74aa562a3b | |||
| 74773ac912 | |||
| 9764d2ad24 | |||
| d03b8c6528 | |||
| 99a355145e | |||
| 7233e2dded | |||
| eed50112d5 | |||
| 5aee5a3f3d | |||
| f21c7ba312 | |||
| 9d7455f022 | |||
| b748e7ed5e | |||
| 84a717c6ad | |||
| a202e1657c | |||
| 30ec919048 | |||
| 4ae4083b7b | |||
| dec9ac1ac8 | |||
| 8776d28d3b | |||
| 231dea0ebc | |||
| cceeb5c8a2 | |||
| 579334b5fc | |||
| 3a82fbe714 | |||
| 143071fa0c | |||
| 0589652edb | |||
| b772d8e527 | |||
| b96d4dcf1f | |||
| dc32e4bdb0 | |||
| 43f2a530f5 | |||
| 6ece593629 | |||
| 33de0ec8a9 | |||
| 8e17714c12 | |||
| 32fc052c3b | |||
| 17febca466 | |||
| 8572a9771b | |||
| 3ea294c0e6 | |||
| 2b3b2e3197 | |||
| a9d9234fb3 | |||
| a11d9b84a4 | |||
| 936ff707c7 | |||
| def69b1aaa | |||
| 4818e1b8ca | |||
| 623f21e51f | |||
| bd524ff2f3 | |||
| 04ab522ee3 | |||
| f672b14468 | |||
| b0973de1a6 | |||
| fe06ef10f1 | |||
| 14ca690441 | |||
| 2de0a3669e | |||
| c7c63e8432 | |||
| adf6afbb43 | |||
| 69b90fb65e | |||
| 97ea68b15c | |||
| badc763c06 | |||
| b6a14d2c9c | |||
| d59dd0f636 | |||
| d68d95a915 | |||
| 15d4344efb | |||
| dc10f18188 | |||
| 2522bfee9c | |||
| d7f8615964 | |||
| 88dff754b1 | |||
| ecd21074fb | |||
| 12caa48390 | |||
| cc7be5f947 | |||
| 5b489e003d | |||
| 8c1f4b006e | |||
| 3a52c19428 | |||
| 279ad6d80a | |||
| b786791401 | |||
| 1c12b6e13b | |||
| c06539dee3 | |||
| 3b9544d1f3 | |||
| da9bb07041 | |||
| 5d9b9ad590 | |||
| f95502ae35 | |||
| 877daba096 | |||
| b3b8ab493e | |||
| 1859c8f5ab | |||
| 87ba042b2d | |||
| 6fb0ef908d | |||
| c4a30cc646 | |||
| cf56f70b3a | |||
| f84e6a34cc | |||
| 85360a7c7f | |||
| 9e0b3afa91 | |||
| 416455fe01 | |||
| 53a1511cac | |||
| 733921f1f9 | |||
| 3ecaa99990 | |||
| ab9729c39a | |||
| 104cc2bf11 | |||
| 1659c3f1a6 | |||
| caa8ec3178 | |||
| 0c794c103b | |||
| 53175d5035 | |||
| 0bd09f9c46 | |||
| 27d795508d | |||
| 368ac5b85d | |||
| d5635f32e5 | |||
| f47075c180 | |||
| 0a5e4b9b7b | |||
| 85624205b4 | |||
| 2330e5ee57 | |||
| c9c5ce6ee0 | |||
| fc3a59d193 | |||
| 950519be5d |
@@ -809,6 +809,26 @@
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "TheVakman",
|
||||
"name": "Lawrence",
|
||||
"avatar_url": "https://avatars1.githubusercontent.com/u/18545156?v=4",
|
||||
"profile": "https://github.com/TheVakman",
|
||||
"contributions": [
|
||||
"test",
|
||||
"bug"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "uknzaeinozpas",
|
||||
"name": "uknzaeinozpas",
|
||||
"avatar_url": "https://avatars1.githubusercontent.com/u/22473767?v=4",
|
||||
"profile": "https://github.com/uknzaeinozpas",
|
||||
"contributions": [
|
||||
"test",
|
||||
"code"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
+1
-1
@@ -97,7 +97,7 @@ LOGIN_LOCKOUT_DURATION=60
|
||||
# --------------------------------------------
|
||||
# OPTIONAL: MISC
|
||||
# --------------------------------------------
|
||||
APP_LOG=daily
|
||||
APP_LOG=single
|
||||
APP_LOG_MAX_FILES=10
|
||||
APP_LOCKED=false
|
||||
FILESYSTEM_DISK=local
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[](https://travis-ci.org/snipe/snipe-it) [](http://waffle.io/snipe/snipe-it) []() [](https://crowdin.com/project/snipe-it) [](https://gitter.im/snipe/snipe-it?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [](https://hub.docker.com/r/snipe/snipe-it/) [](https://twitter.com/snipeyhead) [](https://zenhub.io) [](https://www.codacy.com/app/snipe/snipe-it?utm_source=github.com&utm_medium=referral&utm_content=snipe/snipe-it&utm_campaign=Badge_Grade)
|
||||
[](#contributors)
|
||||
[](#contributors)
|
||||
|
||||
|
||||
## Snipe-IT - Open Source Asset Management System
|
||||
@@ -68,7 +68,7 @@ Thanks goes to all of these wonderful people ([emoji key](https://github.com/ken
|
||||
| [<img src="https://avatars2.githubusercontent.com/u/857740?v=3" width="110px;"/><br /><sub>Gil Rutkowski</sub>](http://FlashingCursor.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=flashingcursor "Code") | [<img src="https://avatars3.githubusercontent.com/u/129360?v=3" width="110px;"/><br /><sub>Desmond Morris</sub>](http://www.desmondmorris.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=desmondmorris "Code") | [<img src="https://avatars2.githubusercontent.com/u/52936?v=3" width="110px;"/><br /><sub>Nick Peelman</sub>](http://peelman.us)<br />[💻](https://github.com/snipe/snipe-it/commits?author=peelman "Code") | [<img src="https://avatars0.githubusercontent.com/u/53161?v=3" width="110px;"/><br /><sub>Abraham Vegh</sub>](https://abrahamvegh.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=abrahamvegh "Code") | [<img src="https://avatars0.githubusercontent.com/u/2818680?v=3" width="110px;"/><br /><sub>Mohamed Rashid</sub>](https://github.com/rashivkp)<br />[📖](https://github.com/snipe/snipe-it/commits?author=rashivkp "Documentation") | [<img src="https://avatars3.githubusercontent.com/u/1509456?v=3" width="110px;"/><br /><sub>Kasey</sub>](http://hinchk.github.io)<br />[💻](https://github.com/snipe/snipe-it/commits?author=HinchK "Code") | [<img src="https://avatars2.githubusercontent.com/u/10522541?v=3" width="110px;"/><br /><sub>Brett</sub>](https://github.com/BrettFagerlund)<br />[⚠️](https://github.com/snipe/snipe-it/commits?author=BrettFagerlund "Tests") |
|
||||
| [<img src="https://avatars2.githubusercontent.com/u/16108587?v=3" width="110px;"/><br /><sub>Jason Spriggs</sub>](http://jasonspriggs.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=jasonspriggs "Code") | [<img src="https://avatars2.githubusercontent.com/u/1134568?v=3" width="110px;"/><br /><sub>Nate Felton</sub>](http://n8felton.wordpress.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=n8felton "Code") | [<img src="https://avatars2.githubusercontent.com/u/14036694?v=3" width="110px;"/><br /><sub>Manasses Ferreira</sub>](http://homepages.dcc.ufmg.br/~manassesferreira)<br />[💻](https://github.com/snipe/snipe-it/commits?author=manassesferreira "Code") | [<img src="https://avatars0.githubusercontent.com/u/15913949?v=3" width="110px;"/><br /><sub>Steve</sub>](https://github.com/steveelwood)<br />[⚠️](https://github.com/snipe/snipe-it/commits?author=steveelwood "Tests") | [<img src="https://avatars1.githubusercontent.com/u/3361683?v=3" width="110px;"/><br /><sub>matc</sub>](http://twitter.com/matc)<br />[⚠️](https://github.com/snipe/snipe-it/commits?author=matc "Tests") | [<img src="https://avatars3.githubusercontent.com/u/7405702?v=3" width="110px;"/><br /><sub>Cole R. Davis</sub>](http://www.davisracingteam.com)<br />[⚠️](https://github.com/snipe/snipe-it/commits?author=VanillaNinjaD "Tests") | [<img src="https://avatars2.githubusercontent.com/u/10167681?v=3" width="110px;"/><br /><sub>gibsonjoshua55</sub>](https://github.com/gibsonjoshua55)<br />[💻](https://github.com/snipe/snipe-it/commits?author=gibsonjoshua55 "Code") |
|
||||
| [<img src="https://avatars2.githubusercontent.com/u/2809241?v=4" width="110px;"/><br /><sub>Robin Temme</sub>](https://github.com/zwerch)<br />[💻](https://github.com/snipe/snipe-it/commits?author=zwerch "Code") | [<img src="https://avatars0.githubusercontent.com/u/6961695?v=4" width="110px;"/><br /><sub>Iman</sub>](https://github.com/imanghafoori1)<br />[💻](https://github.com/snipe/snipe-it/commits?author=imanghafoori1 "Code") | [<img src="https://avatars1.githubusercontent.com/u/6551003?v=4" width="110px;"/><br /><sub>Richard Hofman</sub>](https://github.com/richardhofman6)<br />[💻](https://github.com/snipe/snipe-it/commits?author=richardhofman6 "Code") | [<img src="https://avatars0.githubusercontent.com/u/3697569?v=4" width="110px;"/><br /><sub>gizzmojr</sub>](https://github.com/gizzmojr)<br />[💻](https://github.com/snipe/snipe-it/commits?author=gizzmojr "Code") | [<img src="https://avatars3.githubusercontent.com/u/404729?v=4" width="110px;"/><br /><sub>Jenny Li</sub>](https://github.com/imjennyli)<br />[📖](https://github.com/snipe/snipe-it/commits?author=imjennyli "Documentation") | [<img src="https://avatars0.githubusercontent.com/u/869227?v=4" width="110px;"/><br /><sub>Geoff Young</sub>](https://github.com/GeoffYoung)<br />[💻](https://github.com/snipe/snipe-it/commits?author=GeoffYoung "Code") | [<img src="https://avatars3.githubusercontent.com/u/1068477?v=4" width="110px;"/><br /><sub>Elliot Blackburn</sub>](http://www.elliotblackburn.com)<br />[📖](https://github.com/snipe/snipe-it/commits?author=BlueHatbRit "Documentation") |
|
||||
| [<img src="https://avatars1.githubusercontent.com/u/6357451?v=4" width="110px;"/><br /><sub>Tõnis Ormisson</sub>](http://andmemasin.eu)<br />[💻](https://github.com/snipe/snipe-it/commits?author=TonisOrmisson "Code") | [<img src="https://avatars0.githubusercontent.com/u/449411?v=4" width="110px;"/><br /><sub>Nicolai Essig</sub>](http://www.nicolai-essig.de)<br />[💻](https://github.com/snipe/snipe-it/commits?author=thakilla "Code") | [<img src="https://avatars1.githubusercontent.com/u/14809698?v=4" width="110px;"/><br /><sub>Danielle</sub>](https://github.com/techincolor)<br />[📖](https://github.com/snipe/snipe-it/commits?author=techincolor "Documentation") |
|
||||
| [<img src="https://avatars1.githubusercontent.com/u/6357451?v=4" width="110px;"/><br /><sub>Tõnis Ormisson</sub>](http://andmemasin.eu)<br />[💻](https://github.com/snipe/snipe-it/commits?author=TonisOrmisson "Code") | [<img src="https://avatars0.githubusercontent.com/u/449411?v=4" width="110px;"/><br /><sub>Nicolai Essig</sub>](http://www.nicolai-essig.de)<br />[💻](https://github.com/snipe/snipe-it/commits?author=thakilla "Code") | [<img src="https://avatars1.githubusercontent.com/u/14809698?v=4" width="110px;"/><br /><sub>Danielle</sub>](https://github.com/techincolor)<br />[📖](https://github.com/snipe/snipe-it/commits?author=techincolor "Documentation") | [<img src="https://avatars1.githubusercontent.com/u/18545156?v=4" width="110px;"/><br /><sub>Lawrence</sub>](https://github.com/TheVakman)<br />[⚠️](https://github.com/snipe/snipe-it/commits?author=TheVakman "Tests") [🐛](https://github.com/snipe/snipe-it/issues?q=author%3ATheVakman "Bug reports") | [<img src="https://avatars1.githubusercontent.com/u/22473767?v=4" width="110px;"/><br /><sub>uknzaeinozpas</sub>](https://github.com/uknzaeinozpas)<br />[⚠️](https://github.com/snipe/snipe-it/commits?author=uknzaeinozpas "Tests") [💻](https://github.com/snipe/snipe-it/commits?author=uknzaeinozpas "Code") |
|
||||
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
||||
|
||||
This project follows the [all-contributors](https://github.com/kentcdodds/all-contributors) specification. Contributions of any kind welcome!
|
||||
|
||||
@@ -49,7 +49,7 @@ class RecryptFromMcrypt extends Command
|
||||
// If not, we can try to use the current APP_KEY if looks like it's old
|
||||
$legacy_key = env('LEGACY_APP_KEY');
|
||||
$key_parts = explode(':', $legacy_key);
|
||||
$legacy_cipher = env('LEGACY_CIPHER');
|
||||
$legacy_cipher = env('LEGACY_CIPHER', 'rijndael-256');
|
||||
$errors = array();
|
||||
|
||||
if (!$legacy_key) {
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use App\Models\Asset;
|
||||
use App\Models\Setting;
|
||||
use DB;
|
||||
use Artisan;
|
||||
|
||||
class RegenerateAssetTags extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'snipeit:regenerate-tags {--start=} {--output= : info|warn|error|all} ';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'This utility will regenerate all asset tags. THIS IS DATA-DESTRUCTIVE AND SHOULD BE USED WITH CAUTION. ';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
|
||||
if ($this->confirm('This will regenerate all of the asset tags within your system. This action is data-destructive and should be used with caution. Do you wish to continue?'))
|
||||
{
|
||||
|
||||
$output['info'] = [];
|
||||
$output['warn'] = [];
|
||||
$output['error'] = [];
|
||||
$settings = Setting::getSettings();
|
||||
|
||||
$start_tag = ($this->option('start')) ? $this->option('start') : (($settings->next_auto_tag_base) ? Setting::getSettings()->next_auto_tag_base : 1) ;
|
||||
|
||||
$this->info('Starting at '.$start_tag);
|
||||
|
||||
$total_assets = Asset::orderBy('id','asc')->get();
|
||||
$bar = $this->output->createProgressBar(count($total_assets));
|
||||
|
||||
try {
|
||||
Artisan::call('backup:run');
|
||||
} catch (\Exception $e) {
|
||||
$output['error'][] = $e;
|
||||
}
|
||||
|
||||
foreach ($total_assets as $asset) {
|
||||
|
||||
$start_tag++;
|
||||
$output['info'][] = 'Asset tag:'.$asset->asset_tag;
|
||||
$asset->asset_tag = $settings->auto_increment_prefix.$settings->auto_increment_prefix.$start_tag;
|
||||
|
||||
if ($settings->zerofill_count > 0) {
|
||||
$asset->asset_tag = $settings->auto_increment_prefix.Asset::zerofill($start_tag, $settings->zerofill_count);
|
||||
}
|
||||
|
||||
$output['info'][] = 'New Asset tag:'.$asset->asset_tag;
|
||||
|
||||
// Use forceSave here to override model level validation
|
||||
$asset->forceSave();
|
||||
}
|
||||
|
||||
$bar->finish();
|
||||
$this->info("\n");
|
||||
|
||||
|
||||
if (($this->option('output')=='all') || ($this->option('output')=='info')) {
|
||||
foreach ($output['info'] as $key => $output_text) {
|
||||
$this->info($output_text);
|
||||
}
|
||||
}
|
||||
if (($this->option('output')=='all') || ($this->option('output')=='warn')) {
|
||||
foreach ($output['warn'] as $key => $output_text) {
|
||||
$this->warn($output_text);
|
||||
}
|
||||
}
|
||||
if (($this->option('output')=='all') || ($this->option('output')=='error')) {
|
||||
foreach ($output['error'] as $key => $output_text) {
|
||||
$this->error($output_text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\CustomField;
|
||||
use Illuminate\Console\Command;
|
||||
use App\Models\Asset;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class SyncAssetLocations extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'snipeit:sync-asset-locations {--output= : info|warn|error|all} ';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'This utility will sync the location_id of assets based on current state. It should not normally be needed, but is a safeguard in case we missed something in the Great Migration when flattening the assets to location relationship.';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
|
||||
$output['info'] = [];
|
||||
$output['warn'] = [];
|
||||
$output['error'] = [];
|
||||
|
||||
$total_assets = Asset::whereNull('deleted_at')->get();
|
||||
$bar = $this->output->createProgressBar(count($total_assets));
|
||||
|
||||
// Unassigned
|
||||
$rtd_assets = Asset::whereNull('assigned_to')->whereNull('deleted_at')->with('defaultLoc')->get();
|
||||
$output['info'][] = 'There are '.$rtd_assets->count().' unassigned assets.';
|
||||
|
||||
foreach ($rtd_assets as $rtd_asset) {
|
||||
$output['info'][] = 'Setting Unassigned Asset ' . $rtd_asset->id . ' ('.$rtd_asset->asset_tag.') to location: ' . $rtd_asset->rtd_location_id . " because their default location is: " . $rtd_asset->rtd_location_id;
|
||||
$rtd_asset->location_id=$rtd_asset->rtd_location_id;
|
||||
$rtd_asset->unsetEventDispatcher();
|
||||
$rtd_asset->save();
|
||||
$bar->advance();
|
||||
}
|
||||
|
||||
$assigned_user_assets = Asset::where('assigned_type','App\Models\User')->whereNotNull('assigned_to')->whereNull('deleted_at')->get();
|
||||
$output['info'][] = 'There are '.$assigned_user_assets->count().' assets checked out to users.';
|
||||
foreach ($assigned_user_assets as $assigned_user_asset) {
|
||||
if (($assigned_user_asset->assignedTo) && ($assigned_user_asset->assignedTo->userLoc)) {
|
||||
$new_location=$assigned_user_asset->assignedTo->userloc->id;
|
||||
$output['info'][] ='Setting User Asset ' . $assigned_user_asset->id . ' ('.$assigned_user_asset->asset_tag.') to ' . $assigned_user_asset->assignedTo->userLoc->name . ' which is id: ' . $new_location;
|
||||
} else {
|
||||
$output['warn'][] ='Asset ' . $assigned_user_asset->id . ' ('.$assigned_user_asset->asset_tag.') still has no location! ';
|
||||
$new_location = $assigned_user_asset->rtd_location_id;
|
||||
}
|
||||
$assigned_user_asset->location_id=$new_location;
|
||||
$assigned_user_asset->unsetEventDispatcher();
|
||||
$assigned_user_asset->save();
|
||||
$bar->advance();
|
||||
|
||||
}
|
||||
|
||||
$assigned_location_assets = Asset::where('assigned_type','App\Models\Location')
|
||||
->whereNotNull('assigned_to')->whereNull('deleted_at')->get();
|
||||
$output['info'][] = 'There are '.$assigned_location_assets->count().' assets checked out to locations.';
|
||||
|
||||
foreach ($assigned_location_assets as $assigned_location_asset) {
|
||||
if ($assigned_location_asset->assignedTo) {
|
||||
$assigned_location_asset->location_id = $assigned_location_asset->assignedTo->id;
|
||||
$output['info'][] ='Setting Location Assigned asset ' . $assigned_location_asset->id . ' ('.$assigned_location_asset->asset_tag.') that is checked out to '.$assigned_location_asset->assignedTo->name.' (#'.$assigned_location_asset->assignedTo->id.') to location: ' . $assigned_location_asset->assetLoc()->id;
|
||||
$assigned_location_asset->unsetEventDispatcher();
|
||||
$assigned_location_asset->save();
|
||||
} else {
|
||||
$output['warn'][] ='Asset ' . $assigned_location_asset->id . ' ('.$assigned_location_asset->asset_tag.') did not return a valid associated location - perhaps it was deleted?';
|
||||
}
|
||||
$bar->advance();
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Assigned to assets
|
||||
$assigned_asset_assets = Asset::where('assigned_type','App\Models\Asset')
|
||||
->whereNotNull('assigned_to')->whereNull('deleted_at')->get();
|
||||
$output['info'][] ='Asset-assigned assets: '.$assigned_asset_assets->count();
|
||||
|
||||
foreach ($assigned_asset_assets as $assigned_asset_asset) {
|
||||
|
||||
// Check to make sure there aren't any invalid relationships
|
||||
if ($assigned_asset_asset->assetLoc()) {
|
||||
$assigned_asset_asset->location_id = $assigned_asset_asset->assetLoc()->id;
|
||||
$output['info'][] ='Setting Asset Assigned asset ' . $assigned_asset_asset->assetLoc()->id. ' ('.$assigned_asset_asset->asset_tag.') location to: ' . $assigned_asset_asset->assetLoc()->id;
|
||||
$assigned_asset_asset->unsetEventDispatcher();
|
||||
$assigned_asset_asset->save();
|
||||
} else {
|
||||
$output['warn'][] ='Asset Assigned asset ' . $assigned_asset_asset->assetLoc()->id. ' ('.$assigned_asset_asset->asset_tag.') does not seem to have a valid location';
|
||||
}
|
||||
|
||||
$bar->advance();
|
||||
|
||||
}
|
||||
|
||||
$unlocated_assets = Asset::whereNull("location_id")->whereNull('deleted_at')->get();
|
||||
$output['info'][] ='Assets still without a location: '.$unlocated_assets->count();
|
||||
foreach($unlocated_assets as $unlocated_asset) {
|
||||
$output['warn'][] ='Asset: '.$unlocated_asset->id.' still has no location. ';
|
||||
$bar->advance();
|
||||
}
|
||||
|
||||
$bar->finish();
|
||||
$this->info("\n");
|
||||
|
||||
|
||||
if (($this->option('output')=='all') || ($this->option('output')=='info')) {
|
||||
foreach ($output['info'] as $key => $output_text) {
|
||||
$this->info($output_text);
|
||||
}
|
||||
}
|
||||
if (($this->option('output')=='all') || ($this->option('output')=='warn')) {
|
||||
foreach ($output['warn'] as $key => $output_text) {
|
||||
$this->warn($output_text);
|
||||
}
|
||||
}
|
||||
if (($this->option('output')=='all') || ($this->option('output')=='error')) {
|
||||
foreach ($output['error'] as $key => $output_text) {
|
||||
$this->error($output_text);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class Version extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'version:update {--branch=master} {--type=patch}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Command description';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
|
||||
$use_branch = $this->option('branch');
|
||||
$use_type = $this->option('type');
|
||||
$git_branch = trim(shell_exec('git rev-parse --abbrev-ref HEAD'));
|
||||
$build_version = trim(shell_exec('git rev-list --count '.$use_branch));
|
||||
$versionFile = 'config/version.php';
|
||||
$full_hash_version = str_replace("\n", '', shell_exec('git describe master --tags'));
|
||||
|
||||
$version = explode('-', $full_hash_version);
|
||||
$app_version = $current_app_version = $version[0];
|
||||
$hash_version = $version[2];
|
||||
$prerelease_version = '';
|
||||
|
||||
$this->line('Branch is: '.$use_branch);
|
||||
$this->line('Type is: '.$use_type);
|
||||
$this->line('Current version is: '.$full_hash_version);
|
||||
|
||||
if (count($version)==3) {
|
||||
$this->line('This does not look like an alpha/beta release.');
|
||||
} else {
|
||||
print_r($version);
|
||||
if (array_key_exists('3',$version)) {
|
||||
$this->line('The current version looks like a beta release.');
|
||||
$prerelease_version = $version[1];
|
||||
$hash_version = $version[3];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$app_version_raw = explode('.', $app_version);
|
||||
|
||||
$maj = str_replace('v', '', $app_version_raw[0]);
|
||||
$min = $app_version_raw[1];
|
||||
$patch = '';
|
||||
|
||||
|
||||
|
||||
// This is a major release that might not have a third .0
|
||||
if (array_key_exists(2, $app_version_raw)) {
|
||||
$patch = $app_version_raw[2];
|
||||
}
|
||||
|
||||
if ($use_type=='major') {
|
||||
$app_version = "v".($maj + 1).".$min.$patch";
|
||||
} elseif ($use_type=='minor') {
|
||||
$app_version = "v"."$maj.".($min + 1).".$patch";
|
||||
} elseif ($use_type=='pre') {
|
||||
$pre_raw = str_replace('beta','', $prerelease_version);
|
||||
$pre_raw = str_replace('alpha','', $pre_raw);
|
||||
$pre_raw = str_ireplace('rc','', $pre_raw);
|
||||
$pre_raw = $pre_raw++;
|
||||
$this->line('Setting the pre-release to '. $prerelease_version.'-'.$pre_raw);
|
||||
$app_version = "v"."$maj.".($min + 1).".$patch";
|
||||
} elseif ($use_type=='patch') {
|
||||
$app_version = "v" . "$maj.$min." . ($patch + 1);
|
||||
// If nothing is passed, leave the version as it is, just increment the build
|
||||
} else {
|
||||
$app_version = "v" . "$maj.$min." . $patch;
|
||||
}
|
||||
|
||||
// Determine if this tag already exists, or if this prior to a release
|
||||
$this->line('Running: git rev-parse master '.$current_app_version);
|
||||
// $pre_release = trim(shell_exec('git rev-parse '.$use_branch.' '.$current_app_version.' 2>&1 1> /dev/null'));
|
||||
|
||||
if ($use_branch=='develop') {
|
||||
$app_version = $app_version.'-pre';
|
||||
}
|
||||
|
||||
$full_app_version = $app_version.' - build '.$build_version.'-'.$hash_version;
|
||||
|
||||
|
||||
$array = var_export(
|
||||
array(
|
||||
'app_version' => $app_version,
|
||||
'full_app_version' => $full_app_version,
|
||||
'build_version' => $build_version,
|
||||
'prerelease_version' => $prerelease_version,
|
||||
'hash_version' => $hash_version,
|
||||
'full_hash' => $full_hash_version,
|
||||
'branch' => $git_branch),
|
||||
true
|
||||
);
|
||||
|
||||
|
||||
|
||||
// Construct our file content
|
||||
$content = <<<CON
|
||||
<?php
|
||||
return $array;
|
||||
CON;
|
||||
|
||||
// And finally write the file and output the current version
|
||||
\File::put($versionFile, $content);
|
||||
$this->info('Setting NEW version: '. $full_app_version.' ('.$git_branch.')');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class Versioning extends Command
|
||||
{
|
||||
|
||||
/**
|
||||
* The console command name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $name = 'versioning:update';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Generate and update app\'s version via git.';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function fire()
|
||||
{
|
||||
|
||||
$versionFile = 'config/version.php';
|
||||
$hash_version = str_replace("\n", '', shell_exec('git describe --tags'));
|
||||
|
||||
$version = explode('-', $hash_version);
|
||||
|
||||
$array = var_export(
|
||||
array(
|
||||
'app_version' => $version[0],
|
||||
'build_version' => $version[1],
|
||||
'hash_version' => $version[2],
|
||||
'full_hash' => $hash_version),
|
||||
true
|
||||
);
|
||||
|
||||
|
||||
// Construct our file content
|
||||
$content = <<<CON
|
||||
<?php
|
||||
return $array;
|
||||
CON;
|
||||
|
||||
// And finally write the file and output the current version
|
||||
\File::put($versionFile, $content);
|
||||
$this->line('Setting version: '. config('version.app_version').' build '.config('version.build_version').' ('.config('version.hash_version').')');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the console command arguments.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getArguments()
|
||||
{
|
||||
return array(
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the console command options.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getOptions()
|
||||
{
|
||||
return array(
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -19,14 +19,16 @@ class Kernel extends ConsoleKernel
|
||||
Commands\SendInventoryAlerts::class,
|
||||
Commands\SendExpectedCheckinAlerts::class,
|
||||
Commands\ObjectImportCommand::class,
|
||||
Commands\Versioning::class,
|
||||
Commands\Version::class,
|
||||
Commands\SystemBackup::class,
|
||||
Commands\DisableLDAP::class,
|
||||
Commands\Purge::class,
|
||||
Commands\LdapSync::class,
|
||||
Commands\FixDoubleEscape::class,
|
||||
Commands\RecryptFromMcrypt::class,
|
||||
Commands\ResetDemoSettings::class
|
||||
Commands\ResetDemoSettings::class,
|
||||
Commands\SyncAssetLocations::class,
|
||||
Commands\RegenerateAssetTags::class,
|
||||
];
|
||||
|
||||
/**
|
||||
|
||||
@@ -127,7 +127,13 @@ class Helper
|
||||
$floatString = str_replace(",", "", $floatString);
|
||||
$floatString = str_replace($LocaleInfo["decimal_point"], ".", $floatString);
|
||||
// Strip Currency symbol
|
||||
$floatString = str_replace($LocaleInfo['currency_symbol'], '', $floatString);
|
||||
// If no currency symbol is set, default to $ because Murica
|
||||
$currencySymbol = $LocaleInfo['currency_symbol'];
|
||||
if (empty($currencySymbol)) {
|
||||
$currencySymbol = '$';
|
||||
}
|
||||
|
||||
$floatString = str_replace($currencySymbol, '', $floatString);
|
||||
return floatval($floatString);
|
||||
}
|
||||
|
||||
|
||||
@@ -34,6 +34,10 @@ class AccessoriesController extends Controller
|
||||
$accessories->where('company_id','=',$request->input('company_id'));
|
||||
}
|
||||
|
||||
if ($request->has('category_id')) {
|
||||
$accessories->where('category_id','=',$request->input('category_id'));
|
||||
}
|
||||
|
||||
if ($request->has('manufacturer_id')) {
|
||||
$accessories->where('manufacturer_id','=',$request->input('manufacturer_id'));
|
||||
}
|
||||
|
||||
@@ -56,11 +56,9 @@ class AssetMaintenancesController extends Controller
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
$total = $maintenances->count();
|
||||
$maintenances = $maintenances->skip($offset)->take($limit)->get();
|
||||
|
||||
|
||||
return (new AssetMaintenancesTransformer())->transformAssetMaintenances($maintenances, $maintenances->count());
|
||||
return (new AssetMaintenancesTransformer())->transformAssetMaintenances($maintenances, $total);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -182,21 +182,20 @@ class AssetModelsController extends Controller
|
||||
*/
|
||||
public function selectlist(Request $request)
|
||||
{
|
||||
$this->authorize('view', AssetModel::class);
|
||||
|
||||
$assetmodels = AssetModel::select([
|
||||
'models.id',
|
||||
'models.name',
|
||||
'models.image',
|
||||
'models.model_number',
|
||||
]);
|
||||
])->with('manufacturer');
|
||||
|
||||
|
||||
if ($request->has('search')) {
|
||||
$assetmodels = $assetmodels->where('models.name', 'LIKE', '%'.$request->get('search').'%')
|
||||
->orWhere('models.model_number', 'LIKE', '%'.$request->get('search').'%');
|
||||
}
|
||||
$assetmodels = $assetmodels->paginate(50);
|
||||
$assetmodels = $assetmodels->orderby('models.name', 'asc')->orderby('models.model_number', 'asc')->paginate(50);
|
||||
|
||||
foreach ($assetmodels as $assetmodel) {
|
||||
$assetmodel->use_text = $assetmodel->present()->modelName;
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\Http\Controllers\Api;
|
||||
use App\Helpers\Helper;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\AssetRequest;
|
||||
use App\Http\Requests\AssetCheckoutRequest;
|
||||
use App\Http\Transformers\AssetsTransformer;
|
||||
use App\Models\Asset;
|
||||
use App\Models\AssetModel;
|
||||
@@ -112,7 +113,7 @@ class AssetsController extends Controller
|
||||
}
|
||||
|
||||
if ($request->has('location_id')) {
|
||||
$assets->ByLocationId($request->input('location_id'));
|
||||
$assets->where('assets.location_id', '=', $request->input('location_id'));
|
||||
}
|
||||
|
||||
if ($request->has('supplier_id')) {
|
||||
@@ -275,31 +276,42 @@ class AssetsController extends Controller
|
||||
*/
|
||||
public function selectlist(Request $request)
|
||||
{
|
||||
$this->authorize('view', Asset::class);
|
||||
|
||||
$assets = Company::scopeCompanyables(Asset::select([
|
||||
'assets.id',
|
||||
'assets.name',
|
||||
'assets.asset_tag',
|
||||
'assets.model_id',
|
||||
]))->with('model')->RTD();
|
||||
'assets.assigned_to',
|
||||
'assets.assigned_type',
|
||||
'assets.status_id'
|
||||
])->with('model', 'assetstatus', 'assignedTo')->NotArchived());
|
||||
|
||||
|
||||
if ($request->has('search')) {
|
||||
$assets = $assets->where('assets.name', 'LIKE', '%'.$request->get('search').'%')
|
||||
->orWhere('assets.asset_tag', 'LIKE', '%'.$request->get('search').'%')
|
||||
->join('models AS assets_models',function ($join) use ($request) {
|
||||
$join->on('assets_models.id', "=", "assets.model_id");
|
||||
})->orWhere('assets_models.name','LIKE','%'.$request->get('search').'%');
|
||||
$assets = $assets->AssignedSearch($request->input('search'));
|
||||
}
|
||||
|
||||
|
||||
$assets = $assets->paginate(50);
|
||||
|
||||
// Loop through and set some custom properties for the transformer to use.
|
||||
// This lets us have more flexibility in special cases like assets, where
|
||||
// they may not have a ->name value but we want to display something anyway
|
||||
foreach ($assets as $asset) {
|
||||
|
||||
|
||||
$asset->use_text = $asset->present()->fullName;
|
||||
|
||||
if (($asset->checkedOutToUser()) && ($asset->assigned)) {
|
||||
$asset->use_text .= ' → '.$asset->assigned->getFullNameAttribute();
|
||||
}
|
||||
|
||||
|
||||
if ($asset->assetstatus->getStatuslabelType()=='pending') {
|
||||
$asset->use_text .= '('.$asset->assetstatus->getStatuslabelType().')';
|
||||
}
|
||||
|
||||
$asset->use_image = ($asset->getImageUrl()) ? $asset->getImageUrl() : null;
|
||||
}
|
||||
|
||||
@@ -417,6 +429,8 @@ class AssetsController extends Controller
|
||||
$asset->requestable = $request->get('requestable') : '';
|
||||
($request->has('rtd_location_id')) ?
|
||||
$asset->rtd_location_id = $request->get('rtd_location_id') : '';
|
||||
($request->has('rtd_location_id')) ?
|
||||
$asset->location_id = $request->get('rtd_location_id') : '';
|
||||
($request->has('company_id')) ?
|
||||
$asset->company_id = Company::getIdForCurrentUser($request->get('company_id')) : '';
|
||||
|
||||
@@ -434,14 +448,17 @@ class AssetsController extends Controller
|
||||
|
||||
if ($request->get('assigned_user')) {
|
||||
$target = User::find(request('assigned_user'));
|
||||
$location = $target->location_id;
|
||||
} elseif ($request->get('assigned_asset')) {
|
||||
$target = Asset::find(request('assigned_asset'));
|
||||
$location = $target->location_id;
|
||||
} elseif ($request->get('assigned_location')) {
|
||||
$target = Location::find(request('assigned_location'));
|
||||
$location = $target->id;
|
||||
}
|
||||
|
||||
if (isset($target)) {
|
||||
$asset->checkOut($target, Auth::user(), date('Y-m-d H:i:s'), '', 'Checked out on asset update', e($request->get('name')));
|
||||
$asset->checkOut($target, Auth::user(), date('Y-m-d H:i:s'), '', 'Checked out on asset update', e($request->get('name')), $location);
|
||||
}
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $asset, trans('admin/hardware/message.update.success')));
|
||||
@@ -490,7 +507,7 @@ class AssetsController extends Controller
|
||||
* @since [v4.0]
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function checkout(Request $request, $asset_id)
|
||||
public function checkout(AssetCheckoutRequest $request, $asset_id)
|
||||
{
|
||||
$this->authorize('checkout', Asset::class);
|
||||
$asset = Asset::findOrFail($asset_id);
|
||||
@@ -506,23 +523,37 @@ class AssetsController extends Controller
|
||||
'id' => $asset->id,
|
||||
'asset_tag' => $asset->asset_tag,
|
||||
];
|
||||
if ($request->has('user_id')) {
|
||||
$target = User::find($request->input('user_id'));
|
||||
$error_payload['target_id'] = $request->input('user_id');
|
||||
$error_payload['target_type'] = User::class;
|
||||
// Don't let the user check an asset out to itself
|
||||
} elseif ($request->has('asset_id')) {
|
||||
$target = Asset::where('id','!=',$asset_id)->find($request->input('asset_id'));
|
||||
$error_payload['target_id'] = $request->input('asset_id');
|
||||
$error_payload['target_type'] = Asset::class;
|
||||
} elseif ($request->has('location_id')) {
|
||||
$target = Location::find($request->input('location_id'));
|
||||
$error_payload['target_id'] = $request->input('location_id');
|
||||
$error_payload['target_type'] = Location::class;
|
||||
|
||||
|
||||
// This item is checked out to a location
|
||||
if (request('checkout_to_type')=='location') {
|
||||
$target = Location::find(request('assigned_location'));
|
||||
$asset->location_id = ($target) ? $target->id : '';
|
||||
$error_payload['target_id'] = $request->input('assigned_location');
|
||||
$error_payload['target_type'] = 'location';
|
||||
|
||||
} elseif (request('checkout_to_type')=='asset') {
|
||||
$target = Asset::where('id','!=',$assetId)->find(request('assigned_asset'));
|
||||
$asset->location_id = $target->rtd_location_id;
|
||||
// Override with the asset's location_id if it has one
|
||||
if ($target->location_id!='') {
|
||||
$asset->location_id = ($target) ? $target->location_id : '';
|
||||
}
|
||||
$error_payload['target_id'] = $request->input('assigned_asset');
|
||||
$error_payload['target_type'] = 'asset';
|
||||
|
||||
} elseif (request('checkout_to_type')=='user') {
|
||||
// Fetch the target and set the asset's new location_id
|
||||
$target = User::find(request('assigned_user'));
|
||||
$asset->location_id = ($target) ? $target->location_id : '';
|
||||
$error_payload['target_id'] = $request->input('assigned_user');
|
||||
$error_payload['target_type'] = 'user';
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (!isset($target)) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', $error_payload, 'No valid checkout target specified for asset '.e($asset->asset_tag).'.'));
|
||||
return response()->json(Helper::formatStandardApiResponse('error', $error_payload, 'Checkout target for asset '.e($asset->asset_tag).' is invalid - '.$error_payload['target_type'].' does not exist.'));
|
||||
}
|
||||
|
||||
|
||||
@@ -537,13 +568,11 @@ class AssetsController extends Controller
|
||||
$asset->location_id = $target->rtd_location_id;
|
||||
}
|
||||
|
||||
// Overwrite that if the target has a location ID though
|
||||
if ($target->location_id!='') {
|
||||
$asset->location_id = $target->location_id;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if ($asset->checkOut($target, Auth::user(), $checkout_at, $expected_checkin, $note, $asset_name)) {
|
||||
if ($asset->checkOut($target, Auth::user(), $checkout_at, $expected_checkin, $note, $asset_name, $asset->location_id)) {
|
||||
return response()->json(Helper::formatStandardApiResponse('success', ['asset'=> e($asset->asset_tag)], trans('admin/hardware/message.checkout.success')));
|
||||
}
|
||||
|
||||
@@ -559,7 +588,7 @@ class AssetsController extends Controller
|
||||
* @since [v4.0]
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function checkin($asset_id)
|
||||
public function checkin(Request $request, $asset_id)
|
||||
{
|
||||
$this->authorize('checkin', Asset::class);
|
||||
$asset = Asset::findOrFail($asset_id);
|
||||
@@ -577,6 +606,13 @@ class AssetsController extends Controller
|
||||
$asset->assignedTo()->disassociate($asset);
|
||||
$asset->accepted = null;
|
||||
$asset->name = e(Input::get('name'));
|
||||
$asset->location_id = $asset->rtd_location_id;
|
||||
|
||||
if ($request->has('location_id')) {
|
||||
$asset->location_id = $request->input('location_id');
|
||||
}
|
||||
|
||||
$asset->location_id = $asset->rtd_location_id;
|
||||
|
||||
if (Input::has('status_id')) {
|
||||
$asset->status_id = e(Input::get('status_id'));
|
||||
|
||||
@@ -21,7 +21,7 @@ class CategoriesController extends Controller
|
||||
public function index(Request $request)
|
||||
{
|
||||
$this->authorize('view', Category::class);
|
||||
$allowed_columns = ['id', 'name','category_type','use_default_eula','eula_text', 'require_acceptance','checkin_email', 'assets_count', 'accessories_count', 'consumables_count', 'components_count', 'image'];
|
||||
$allowed_columns = ['id', 'name','category_type', 'category_type','use_default_eula','eula_text', 'require_acceptance','checkin_email', 'assets_count', 'accessories_count', 'consumables_count', 'components_count', 'image'];
|
||||
|
||||
$categories = Category::select(['id', 'created_at', 'updated_at', 'name','category_type','use_default_eula','eula_text', 'require_acceptance','checkin_email','image'])
|
||||
->withCount('assets', 'accessories', 'consumables', 'components');
|
||||
@@ -141,7 +141,6 @@ class CategoriesController extends Controller
|
||||
*/
|
||||
public function selectlist(Request $request, $category_type = 'asset')
|
||||
{
|
||||
$this->authorize('view', Categories::class);
|
||||
|
||||
$categories = Category::select([
|
||||
'id',
|
||||
|
||||
@@ -153,7 +153,6 @@ class CompaniesController extends Controller
|
||||
*/
|
||||
public function selectlist(Request $request)
|
||||
{
|
||||
$this->authorize('view', Company::class);
|
||||
|
||||
$companies = Company::select([
|
||||
'companies.id',
|
||||
|
||||
@@ -160,7 +160,6 @@ class ConsumablesController extends Controller
|
||||
*/
|
||||
public function getDataView($consumableId)
|
||||
{
|
||||
//$consumable = Consumable::find($consumableID);
|
||||
$consumable = Consumable::with(array('consumableAssignments'=>
|
||||
function ($query) {
|
||||
$query->orderBy('created_at', 'DESC');
|
||||
@@ -171,17 +170,15 @@ class ConsumablesController extends Controller
|
||||
},
|
||||
))->find($consumableId);
|
||||
|
||||
// $consumable->load('consumableAssignments.admin','consumableAssignments.user');
|
||||
|
||||
if (!Company::isCurrentUserHasAccess($consumable)) {
|
||||
return ['total' => 0, 'rows' => []];
|
||||
}
|
||||
$this->authorize('view', Component::class);
|
||||
$this->authorize('view', Consumable::class);
|
||||
$rows = array();
|
||||
|
||||
foreach ($consumable->consumableAssignments as $consumable_assignment) {
|
||||
$rows[] = [
|
||||
'name' => $consumable_assignment->user->present()->nameUrl(),
|
||||
'name' => ($consumable_assignment->user) ? $consumable_assignment->user->present()->nameUrl() : 'Deleted User',
|
||||
'created_at' => ($consumable_assignment->created_at->format('Y-m-d H:i:s')=='-0001-11-30 00:00:00') ? '' : $consumable_assignment->created_at->format('Y-m-d H:i:s'),
|
||||
'admin' => ($consumable_assignment->admin) ? $consumable_assignment->admin->present()->nameUrl() : '',
|
||||
];
|
||||
|
||||
@@ -122,7 +122,6 @@ class DepartmentsController extends Controller
|
||||
*/
|
||||
public function selectlist(Request $request)
|
||||
{
|
||||
$this->authorize('view', Department::class);
|
||||
|
||||
$departments = Department::select([
|
||||
'id',
|
||||
|
||||
@@ -21,7 +21,7 @@ class LicensesController extends Controller
|
||||
public function index(Request $request)
|
||||
{
|
||||
$this->authorize('view', License::class);
|
||||
$licenses = Company::scopeCompanyables(License::with('company', 'licenseSeatsRelation', 'manufacturer', 'supplier'));
|
||||
$licenses = Company::scopeCompanyables(License::with('company', 'manufacturer', 'freeSeats', 'supplier')->withCount('freeSeats'));
|
||||
|
||||
if ($request->has('search')) {
|
||||
$licenses = $licenses->TextSearch($request->input('search'));
|
||||
@@ -77,17 +77,17 @@ class LicensesController extends Controller
|
||||
|
||||
|
||||
switch ($request->input('sort')) {
|
||||
case 'manufacturer':
|
||||
$licenses = $licenses->OrderManufacturer($order);
|
||||
case 'manufacturer':
|
||||
$licenses = $licenses->leftJoin('manufacturers', 'licenses.manufacturer_id', '=', 'manufacturers.id')->orderBy('manufacturers.name', $order);
|
||||
break;
|
||||
case 'supplier':
|
||||
$licenses = $licenses->OrderSupplier($order);
|
||||
$licenses = $licenses->leftJoin('suppliers', 'licenses.supplier_id', '=', 'suppliers.id')->orderBy('suppliers.name', $order);
|
||||
break;
|
||||
case 'company':
|
||||
$licenses = $licenses->OrderCompany($order);
|
||||
$licenses = $licenses->leftJoin('companies', 'licenses.company_id', '=', 'companies.id')->orderBy('companies.name', $order);
|
||||
break;
|
||||
default:
|
||||
$allowed_columns = ['id','name','purchase_cost','expiration_date','purchase_order','order_number','notes','purchase_date','serial','company','license_name','license_email'];
|
||||
$allowed_columns = ['id','name','purchase_cost','expiration_date','purchase_order','order_number','notes','purchase_date','serial','company','license_name','license_email','free_seats_count','seats'];
|
||||
$sort = in_array($request->input('sort'), $allowed_columns) ? e($request->input('sort')) : 'created_at';
|
||||
$licenses = $licenses->orderBy($sort, $order);
|
||||
break;
|
||||
@@ -95,6 +95,7 @@ class LicensesController extends Controller
|
||||
|
||||
|
||||
$total = $licenses->count();
|
||||
|
||||
$licenses = $licenses->skip($offset)->take($limit)->get();
|
||||
return (new LicensesTransformer)->transformLicenses($licenses, $total);
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ class LocationsController extends Controller
|
||||
$allowed_columns = [
|
||||
'id','name','address','address2','city','state','country','zip','created_at',
|
||||
'updated_at','parent_id', 'manager_id','image',
|
||||
'rtd_assets_count','users_count','assets_count'];
|
||||
'assigned_assets_count','users_count','assets_count'];
|
||||
|
||||
$locations = Location::with('parent', 'manager', 'childLocations')->select([
|
||||
'locations.id',
|
||||
@@ -41,7 +41,7 @@ class LocationsController extends Controller
|
||||
'locations.updated_at',
|
||||
'locations.image',
|
||||
'locations.currency'
|
||||
])->withCount('rtd_assets')
|
||||
])->withCount('assignedAssets')
|
||||
->withCount('assets')
|
||||
->withCount('users');
|
||||
|
||||
@@ -152,7 +152,6 @@ class LocationsController extends Controller
|
||||
*/
|
||||
public function selectlist(Request $request)
|
||||
{
|
||||
$this->authorize('view', Location::class);
|
||||
|
||||
$locations = Location::select([
|
||||
'locations.id',
|
||||
|
||||
@@ -132,7 +132,6 @@ class ManufacturersController extends Controller
|
||||
*/
|
||||
public function selectlist(Request $request)
|
||||
{
|
||||
$this->authorize('view', Manufacturers::class);
|
||||
|
||||
$manufacturers = Manufacturer::select([
|
||||
'id',
|
||||
|
||||
@@ -50,11 +50,9 @@ class ReportsController extends Controller
|
||||
$offset = request('offset', 0);
|
||||
$limit = request('limit', 50);
|
||||
$total = $actionlogs->count();
|
||||
$actionlogs = $actionlogs->orderBy($sort, $order);
|
||||
$actionlogs = $actionlogs->skip($offset)->take($limit)->get();
|
||||
return (new ActionlogsTransformer)->transformActionlogs($actionlogs, $total);
|
||||
|
||||
$actionlogs = $actionlogs->orderBy($sort, $order)->skip($offset)->take($limit)->get();
|
||||
|
||||
return response()->json((new ActionlogsTransformer)->transformActionlogs($actionlogs, $total), 200, ['Content-Type' => 'application/json;charset=utf8'], JSON_UNESCAPED_UNICODE);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,11 +108,11 @@ class SettingsController extends Controller
|
||||
if (!config('app.lock_passwords')) {
|
||||
try {
|
||||
Mail::send('emails.test', [], function ($m) {
|
||||
$m->to(config('mail.from.address'), config('mail.from.name'));
|
||||
$m->to(config('mail.reply_to.address'), config('mail.reply_to.name'));
|
||||
$m->replyTo(config('mail.reply_to.address'), config('mail.reply_to.name'));
|
||||
$m->subject(trans('mail.test_email'));
|
||||
});
|
||||
return response()->json(['message' => 'Mail sent to '.config('mail.from.address')], 200);
|
||||
return response()->json(['message' => 'Mail sent to '.config('mail.reply_to.address')], 200);
|
||||
} catch (Exception $e) {
|
||||
return response()->json(['message' => $e->getMessage()], 500);
|
||||
}
|
||||
|
||||
@@ -146,7 +146,6 @@ class SuppliersController extends Controller
|
||||
*/
|
||||
public function selectlist(Request $request)
|
||||
{
|
||||
$this->authorize('view', Supplier::class);
|
||||
|
||||
$suppliers = Supplier::select([
|
||||
'id',
|
||||
|
||||
@@ -80,7 +80,7 @@ class UsersController extends Controller
|
||||
}
|
||||
|
||||
if ($request->has('department_id')) {
|
||||
$users = $users->where('department_id','=',$request->input('department_id'));
|
||||
$users = $users->where('users.department_id','=',$request->input('department_id'));
|
||||
}
|
||||
|
||||
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
|
||||
@@ -127,7 +127,6 @@ class UsersController extends Controller
|
||||
*/
|
||||
public function selectlist(Request $request)
|
||||
{
|
||||
$this->authorize('view', User::class);
|
||||
|
||||
$users = User::select(
|
||||
[
|
||||
@@ -225,6 +224,10 @@ class UsersController extends Controller
|
||||
$user = User::findOrFail($id);
|
||||
$user->fill($request->all());
|
||||
|
||||
if ($user->id == $request->input('manager_id')) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, 'You cannot be your own manager'));
|
||||
}
|
||||
|
||||
if ($request->has('password')) {
|
||||
$user->password = bcrypt($request->input('password'));
|
||||
}
|
||||
|
||||
@@ -154,16 +154,21 @@ class AssetMaintenancesController extends Controller
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
$asset = null;
|
||||
|
||||
if ($asset = Asset::find(request('asset_id'))) {
|
||||
// We have to set this so that the correct property is set in the select2 ajax dropdown
|
||||
$asset->asset_id = $asset->id;
|
||||
}
|
||||
|
||||
// Prepare Asset Maintenance Type List
|
||||
$assetMaintenanceType = [
|
||||
'' => 'Select an asset maintenance type',
|
||||
] + AssetMaintenance::getImprovementOptions();
|
||||
// Mark the selected asset, if it came in
|
||||
// Render the view
|
||||
|
||||
return view('asset_maintenances/edit')
|
||||
->with('asset_list', Helper::detailedAssetList())
|
||||
->with('selectedAsset', request('asset_id'))
|
||||
->with('supplier_list', Helper::suppliersList())
|
||||
->with('asset', $asset)
|
||||
->with('assetMaintenanceType', $assetMaintenanceType)
|
||||
->with('item', new AssetMaintenance);
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ class AssetModelsController extends Controller
|
||||
|
||||
$image = Input::file('image');
|
||||
$file_name = str_slug($image->getClientOriginalName()) . "." . $image->getClientOriginalExtension();
|
||||
$path = public_path('uploads/models/');
|
||||
$path = app('models_upload_path');
|
||||
|
||||
if ($image->getClientOriginalExtension()!='svg') {
|
||||
Image::make($image->getRealPath())->resize(500, null, function ($constraint) {
|
||||
@@ -191,15 +191,14 @@ class AssetModelsController extends Controller
|
||||
return redirect()->route('models.index')->with('error', trans('admin/models/message.does_not_exist'));
|
||||
}
|
||||
|
||||
$model->depreciation_id = $request->input('depreciation_id');
|
||||
$model->eol = $request->input('eol');
|
||||
$model->depreciation_id = $request->input('depreciation_id');
|
||||
$model->eol = $request->input('eol');
|
||||
$model->name = $request->input('name');
|
||||
$model->model_number = $request->input('model_number');
|
||||
$model->manufacturer_id = $request->input('manufacturer_id');
|
||||
$model->category_id = $request->input('category_id');
|
||||
$model->notes = $request->input('notes');
|
||||
|
||||
$model->requestable = Input::has('requestable');
|
||||
$model->requestable = $request->input('requestable', '0');
|
||||
|
||||
if ($request->input('custom_fieldset')=='') {
|
||||
$model->fieldset_id = null;
|
||||
@@ -207,35 +206,38 @@ class AssetModelsController extends Controller
|
||||
$model->fieldset_id = $request->input('custom_fieldset');
|
||||
}
|
||||
|
||||
if (Input::file('image')) {
|
||||
$old_image = $model->image;
|
||||
|
||||
$image = Input::file('image');
|
||||
$file_name = str_slug($image->getClientOriginalName()) . "." . $image->getClientOriginalExtension();
|
||||
$path = public_path('uploads/models/');
|
||||
$old_image = $path.$model->image;
|
||||
// Set the model's image property to null if the image is being deleted
|
||||
if ($request->input('image_delete') == 1) {
|
||||
$model->image = null;
|
||||
}
|
||||
|
||||
try {
|
||||
unlink($old_image);
|
||||
} catch (\Exception $e) {
|
||||
\Log::error($e);
|
||||
}
|
||||
if ($request->file('image')) {
|
||||
$image = $request->file('image');
|
||||
$file_name = $model->id.'-'.str_slug($image->getClientOriginalName()) . "." . $image->getClientOriginalExtension();
|
||||
|
||||
if ($image->getClientOriginalExtension()!='svg') {
|
||||
Image::make($image->getRealPath())->resize(500, null, function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
})->save($path.'/'.$file_name);
|
||||
})->save(app('models_upload_path').$file_name);
|
||||
} else {
|
||||
$image->move($path, $file_name);
|
||||
$image->move(app('models_upload_path'), $file_name);
|
||||
}
|
||||
$model->image = $file_name;
|
||||
|
||||
}
|
||||
|
||||
if ($request->input('image_delete') == 1 && Input::file('image') == "") {
|
||||
$model->image = null;
|
||||
if ((($request->file('image')) && (isset($old_image)) && ($old_image!='')) || ($request->input('image_delete') == 1)) {
|
||||
try {
|
||||
unlink(app('models_upload_path').$old_image);
|
||||
} catch (\Exception $e) {
|
||||
\Log::error($e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ($model->save()) {
|
||||
return redirect()->route("models.index")->with('success', trans('admin/models/message.update.success'));
|
||||
}
|
||||
|
||||
@@ -160,6 +160,10 @@ class AssetsController extends Controller
|
||||
$asset->requestable = request('requestable', 0);
|
||||
$asset->rtd_location_id = request('rtd_location_id', null);
|
||||
|
||||
if ($asset->assigned_to=='') {
|
||||
$asset->location_id = $request->input('rtd_location_id', null);
|
||||
}
|
||||
|
||||
// Create the image (if one was chosen.)
|
||||
if ($request->has('image')) {
|
||||
$image = $request->input('image');
|
||||
@@ -199,8 +203,6 @@ class AssetsController extends Controller
|
||||
|
||||
// Update custom fields in the database.
|
||||
// Validation for these fields is handled through the AssetRequest form request
|
||||
// FIXME: No idea why this is returning a Builder error on db_column_name.
|
||||
// Need to investigate and fix. Using static method for now.
|
||||
$model = AssetModel::find($request->get('model_id'));
|
||||
|
||||
if ($model->fieldset) {
|
||||
@@ -218,15 +220,20 @@ class AssetsController extends Controller
|
||||
// Was the asset created?
|
||||
if ($asset->save()) {
|
||||
$asset->logCreate();
|
||||
|
||||
if (request('assigned_user')) {
|
||||
$target = User::find(request('assigned_user'));
|
||||
$location = $target->location_id;
|
||||
} elseif (request('assigned_asset')) {
|
||||
$target = Asset::find(request('assigned_asset'));
|
||||
$location = $target->location_id;
|
||||
} elseif (request('assigned_location')) {
|
||||
$target = Location::find(request('assigned_location'));
|
||||
$location = $target->id;
|
||||
}
|
||||
|
||||
if (isset($target)) {
|
||||
$asset->checkOut($target, Auth::user(), date('Y-m-d H:i:s'), '', 'Checked out on asset creation', e(Input::get('name')));
|
||||
$asset->checkOut($target, Auth::user(), date('Y-m-d H:i:s'), '', 'Checked out on asset creation', e(Input::get('name')), $location);
|
||||
}
|
||||
// Redirect to the asset listing page
|
||||
\Session::flash('success', trans('admin/hardware/message.create.success'));
|
||||
@@ -289,6 +296,11 @@ class AssetsController extends Controller
|
||||
$asset->requestable = $request->has('requestable');
|
||||
$asset->rtd_location_id = $request->input('rtd_location_id', null);
|
||||
|
||||
if ($asset->assigned_to=='') {
|
||||
$asset->location_id = $request->input('rtd_location_id', null);
|
||||
}
|
||||
|
||||
|
||||
if ($request->has('image_delete')) {
|
||||
unlink(public_path().'/uploads/assets/'.$asset->image);
|
||||
$asset->image = '';
|
||||
@@ -419,8 +431,13 @@ class AssetsController extends Controller
|
||||
|
||||
$this->authorize('checkout', $asset);
|
||||
|
||||
if ($asset->availableForCheckout()) {
|
||||
return view('hardware/checkout', compact('asset'));
|
||||
}
|
||||
return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.checkout.not_available'));
|
||||
|
||||
// Get the dropdown of users and then pass it to the checkout view
|
||||
return view('hardware/checkout', compact('asset'));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -441,17 +458,34 @@ class AssetsController extends Controller
|
||||
return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.checkout.not_available'));
|
||||
}
|
||||
$this->authorize('checkout', $asset);
|
||||
|
||||
if (request('assigned_user')) {
|
||||
$target = User::find(request('assigned_user'));
|
||||
} elseif (request('assigned_asset')) {
|
||||
$target = Asset::where('id','!=',$assetId)->find(request('assigned_asset'));
|
||||
} elseif (request('assigned_location')) {
|
||||
$target = Location::find(request('assigned_location'));
|
||||
}
|
||||
// $user = User::find(Input::get('assigned_to'));
|
||||
$admin = Auth::user();
|
||||
|
||||
|
||||
// This item is checked out to a location
|
||||
if (request('checkout_to_type')=='location') {
|
||||
$target = Location::find(request('assigned_location'));
|
||||
$asset->location_id = ($target) ? $target->id : '';
|
||||
|
||||
} elseif (request('checkout_to_type')=='asset') {
|
||||
$target = Asset::where('id','!=',$assetId)->find(request('assigned_asset'));
|
||||
$asset->location_id = $target->rtd_location_id;
|
||||
// Override with the asset's location_id if it has one
|
||||
if ($target->location_id!='') {
|
||||
$asset->location_id = ($target) ? $target->location_id : '';
|
||||
}
|
||||
|
||||
} elseif (request('checkout_to_type')=='user') {
|
||||
// Fetch the target and set the asset's new location_id
|
||||
$target = User::find(request('assigned_user'));
|
||||
$asset->location_id = ($target) ? $target->location_id : '';
|
||||
}
|
||||
|
||||
// No valid target was found - error out
|
||||
if (!$target) {
|
||||
return redirect()->back()->with('error', trans('admin/hardware/message.checkout.error'))->withErrors($asset->getErrors());
|
||||
}
|
||||
|
||||
|
||||
if ((Input::has('checkout_at')) && (Input::get('checkout_at')!= date("Y-m-d"))) {
|
||||
$checkout_at = Input::get('checkout_at');
|
||||
} else {
|
||||
@@ -464,22 +498,12 @@ class AssetsController extends Controller
|
||||
$expected_checkin = '';
|
||||
}
|
||||
|
||||
// Set the location ID to the RTD location id if there is one
|
||||
if ($asset->rtd_location_id!='') {
|
||||
$asset->location_id = $target->rtd_location_id;
|
||||
}
|
||||
|
||||
// Overwrite that if the target has a location ID though
|
||||
if ($target->location_id!='') {
|
||||
$asset->location_id = $target->location_id;
|
||||
}
|
||||
|
||||
if ($asset->checkOut($target, $admin, $checkout_at, $expected_checkin, e(Input::get('note')), Input::get('name'))) {
|
||||
// Redirect to the new asset page
|
||||
return redirect()->route("hardware.index")->with('success', trans('admin/hardware/message.checkout.success'));
|
||||
}
|
||||
|
||||
// Redirect to the asset management page with error
|
||||
// Redirect to the asset management page with error
|
||||
return redirect()->to("hardware/$assetId/checkout")->with('error', trans('admin/hardware/message.checkout.error'))->withErrors($asset->getErrors());
|
||||
}
|
||||
|
||||
@@ -546,6 +570,8 @@ class AssetsController extends Controller
|
||||
$asset->status_id = e(Input::get('status_id'));
|
||||
}
|
||||
|
||||
$asset->location_id = $asset->rtd_location_id;
|
||||
|
||||
if (Input::has('location_id')) {
|
||||
$asset->location_id = e(Input::get('location_id'));
|
||||
}
|
||||
@@ -643,20 +669,23 @@ class AssetsController extends Controller
|
||||
|
||||
if ($settings->qr_code == '1') {
|
||||
$asset = Asset::withTrashed()->find($assetId);
|
||||
$size = Helper::barcodeDimensions($settings->barcode_type);
|
||||
$qr_file = public_path().'/uploads/barcodes/qr-'.str_slug($asset->asset_tag).'-'.str_slug($asset->id).'.png';
|
||||
if ($asset) {
|
||||
$size = Helper::barcodeDimensions($settings->barcode_type);
|
||||
$qr_file = public_path().'/uploads/barcodes/qr-'.str_slug($asset->asset_tag).'-'.str_slug($asset->id).'.png';
|
||||
|
||||
if (isset($asset->id, $asset->asset_tag)) {
|
||||
if (file_exists($qr_file)) {
|
||||
$header = ['Content-type' => 'image/png'];
|
||||
return response()->file($qr_file, $header);
|
||||
} else {
|
||||
$barcode = new \Com\Tecnick\Barcode\Barcode();
|
||||
$barcode_obj = $barcode->getBarcodeObj($settings->barcode_type, route('hardware.show', $asset->id), $size['height'], $size['width'], 'black', array(-2, -2, -2, -2));
|
||||
file_put_contents($qr_file, $barcode_obj->getPngData());
|
||||
return response($barcode_obj->getPngData())->header('Content-type', 'image/png');
|
||||
if (isset($asset->id, $asset->asset_tag)) {
|
||||
if (file_exists($qr_file)) {
|
||||
$header = ['Content-type' => 'image/png'];
|
||||
return response()->file($qr_file, $header);
|
||||
} else {
|
||||
$barcode = new \Com\Tecnick\Barcode\Barcode();
|
||||
$barcode_obj = $barcode->getBarcodeObj($settings->barcode_type, route('hardware.show', $asset->id), $size['height'], $size['width'], 'black', array(-2, -2, -2, -2));
|
||||
file_put_contents($qr_file, $barcode_obj->getPngData());
|
||||
return response($barcode_obj->getPngData())->header('Content-type', 'image/png');
|
||||
}
|
||||
}
|
||||
}
|
||||
return 'That asset is invalid';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -916,8 +945,8 @@ class AssetsController extends Controller
|
||||
|
||||
$destinationPath = config('app.private_uploads').'/assets';
|
||||
|
||||
if ($request->hasFile('image')) {
|
||||
foreach ($request->file('image') as $file) {
|
||||
if ($request->hasFile('assetfile')) {
|
||||
foreach ($request->file('assetfile') as $file) {
|
||||
$extension = $file->getClientOriginalExtension();
|
||||
$filename = 'hardware-'.$asset->id.'-'.str_random(8);
|
||||
$filename .= '-'.str_slug($file->getClientOriginalName()).'.'.$extension;
|
||||
@@ -1052,70 +1081,73 @@ class AssetsController extends Controller
|
||||
* @internal param array $assets
|
||||
* @since [v2.0]
|
||||
*/
|
||||
public function postBulkSave()
|
||||
public function postBulkSave(Request $request)
|
||||
{
|
||||
$this->authorize('update', Asset::class);
|
||||
if (Input::has('ids')) {
|
||||
$assets = Input::get('ids');
|
||||
if ((Input::has('purchase_date'))
|
||||
|| (Input::has('purchase_cost'))
|
||||
|| (Input::has('supplier_id'))
|
||||
|| (Input::has('order_number'))
|
||||
|| (Input::has('warranty_months'))
|
||||
|| (Input::has('rtd_location_id'))
|
||||
|| (Input::has('requestable'))
|
||||
|| (Input::has('company_id'))
|
||||
|| (Input::has('status_id'))
|
||||
|| (Input::has('model_id'))
|
||||
|
||||
\Log::debug($request->input('ids'));
|
||||
|
||||
if (($request->has('ids')) && (count($request->input('ids') > 0))) {
|
||||
$assets = $request->input('ids');
|
||||
if (($request->has('purchase_date'))
|
||||
|| ($request->has('purchase_cost'))
|
||||
|| ($request->has('supplier_id'))
|
||||
|| ($request->has('order_number'))
|
||||
|| ($request->has('warranty_months'))
|
||||
|| ($request->has('rtd_location_id'))
|
||||
|| ($request->has('requestable'))
|
||||
|| ($request->has('company_id'))
|
||||
|| ($request->has('status_id'))
|
||||
|| ($request->has('model_id'))
|
||||
) {
|
||||
foreach ($assets as $key => $value) {
|
||||
$update_array = array();
|
||||
|
||||
if (Input::has('purchase_date')) {
|
||||
$update_array['purchase_date'] = e(Input::get('purchase_date'));
|
||||
if ($request->has('purchase_date')) {
|
||||
$update_array['purchase_date'] = $request->input('purchase_date');
|
||||
}
|
||||
if (Input::has('purchase_cost')) {
|
||||
$update_array['purchase_cost'] = Helper::ParseFloat(e(Input::get('purchase_cost')));
|
||||
if ($request->has('purchase_cost')) {
|
||||
$update_array['purchase_cost'] = Helper::ParseFloat($request->input('purchase_cost'));
|
||||
}
|
||||
if (Input::has('supplier_id')) {
|
||||
$update_array['supplier_id'] = e(Input::get('supplier_id'));
|
||||
if ($request->has('supplier_id')) {
|
||||
$update_array['supplier_id'] = $request->input('supplier_id');
|
||||
}
|
||||
if (Input::has('model_id')) {
|
||||
$update_array['model_id'] = e(Input::get('model_id'));
|
||||
if ($request->has('model_id')) {
|
||||
$update_array['model_id'] = $request->input('model_id');
|
||||
}
|
||||
if (Input::has('company_id')) {
|
||||
if (Input::get('company_id')=="clear") {
|
||||
if ($request->has('company_id')) {
|
||||
if ($request->input('company_id')=="clear") {
|
||||
$update_array['company_id'] = null;
|
||||
} else {
|
||||
$update_array['company_id'] = e(Input::get('company_id'));
|
||||
$update_array['company_id'] = $request->input('company_id');
|
||||
}
|
||||
}
|
||||
if (Input::has('order_number')) {
|
||||
$update_array['order_number'] = e(Input::get('order_number'));
|
||||
if ($request->has('order_number')) {
|
||||
$update_array['order_number'] = $request->input('order_number');
|
||||
}
|
||||
if (Input::has('warranty_months')) {
|
||||
$update_array['warranty_months'] = e(Input::get('warranty_months'));
|
||||
if ($request->has('warranty_months')) {
|
||||
$update_array['warranty_months'] = $request->input('warranty_months');
|
||||
}
|
||||
if (Input::has('rtd_location_id')) {
|
||||
$update_array['rtd_location_id'] = e(Input::get('rtd_location_id'));
|
||||
if ($request->has('rtd_location_id')) {
|
||||
$update_array['rtd_location_id'] = $request->input('rtd_location_id');
|
||||
}
|
||||
if (Input::has('status_id')) {
|
||||
$update_array['status_id'] = e(Input::get('status_id'));
|
||||
if ($request->has('status_id')) {
|
||||
$update_array['status_id'] = $request->input('status_id');
|
||||
}
|
||||
if (Input::has('requestable')) {
|
||||
$update_array['requestable'] = e(Input::get('requestable'));
|
||||
if ($request->has('requestable')) {
|
||||
$update_array['requestable'] = $request->input('requestable');
|
||||
}
|
||||
|
||||
DB::table('assets')
|
||||
->where('id', $key)
|
||||
->update($update_array);
|
||||
} // endforeach
|
||||
return redirect()->to("hardware")->with('success', trans('admin/hardware/message.update.success'));
|
||||
return redirect()->route("hardware.index")->with('success', trans('admin/hardware/message.update.success'));
|
||||
// no values given, nothing to update
|
||||
}
|
||||
return redirect()->to("hardware")->with('info', trans('admin/hardware/message.update.nothing_updated'));
|
||||
return redirect()->route("hardware.index")->with('warning', trans('admin/hardware/message.update.nothing_updated'));
|
||||
} // endif
|
||||
return redirect()->to("hardware");
|
||||
return redirect()->route("hardware.index")->with('warning', trans('No assets selected, so nothing was updated.'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1216,8 +1248,9 @@ class AssetsController extends Controller
|
||||
|
||||
public function audit($id)
|
||||
{
|
||||
$settings = Setting::getSettings();
|
||||
$this->authorize('audit', Asset::class);
|
||||
$dt = Carbon::now()->addMonths(12)->toDateString();
|
||||
$dt = Carbon::now()->addMonths($settings->audit_interval)->toDateString();
|
||||
$asset = Asset::findOrFail($id);
|
||||
return view('hardware/audit')->with('asset', $asset)->with('next_audit_date', $dt)->with('locations_list');
|
||||
}
|
||||
|
||||
@@ -71,9 +71,7 @@ class CategoriesController extends Controller
|
||||
*/
|
||||
public function store(ImageUploadRequest $request)
|
||||
{
|
||||
// create a new model instance
|
||||
$category = new Category();
|
||||
// Update the category data
|
||||
$category->name = $request->input('name');
|
||||
$category->category_type = $request->input('category_type');
|
||||
$category->eula_text = $request->input('eula_text');
|
||||
@@ -150,17 +148,35 @@ class CategoriesController extends Controller
|
||||
$category->require_acceptance = $request->input('require_acceptance', '0');
|
||||
$category->checkin_email = $request->input('checkin_email', '0');
|
||||
|
||||
$old_image = $category->image;
|
||||
|
||||
// Set the model's image property to null if the image is being deleted
|
||||
if ($request->input('image_delete') == 1) {
|
||||
$category->image = null;
|
||||
}
|
||||
|
||||
if ($request->file('image')) {
|
||||
$image = $request->file('image');
|
||||
$file_name = str_random(25).".".$image->getClientOriginalExtension();
|
||||
$path = public_path('uploads/categories/'.$file_name);
|
||||
Image::make($image->getRealPath())->resize(200, null, function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
})->save($path);
|
||||
$file_name = $category->id.'-'.str_slug($image->getClientOriginalName()) . "." . $image->getClientOriginalExtension();
|
||||
|
||||
if ($image->getClientOriginalExtension()!='svg') {
|
||||
Image::make($image->getRealPath())->resize(500, null, function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
})->save(app('categories_upload_path').$file_name);
|
||||
} else {
|
||||
$image->move(app('categories_upload_path'), $file_name);
|
||||
}
|
||||
$category->image = $file_name;
|
||||
} elseif ($request->input('image_delete')=='1') {
|
||||
$category->image = null;
|
||||
|
||||
}
|
||||
|
||||
if ((($request->file('image')) && (isset($old_image)) && ($old_image!='')) || ($request->input('image_delete') == 1)) {
|
||||
try {
|
||||
unlink(app('categories_upload_path').$old_image);
|
||||
} catch (\Exception $e) {
|
||||
\Log::error($e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -110,17 +110,35 @@ final class CompaniesController extends Controller
|
||||
|
||||
$company->name = $request->input('name');
|
||||
|
||||
$old_image = $company->image;
|
||||
|
||||
// Set the model's image property to null if the image is being deleted
|
||||
if ($request->input('image_delete') == 1) {
|
||||
$company->image = null;
|
||||
}
|
||||
|
||||
if ($request->file('image')) {
|
||||
$image = $request->file('image');
|
||||
$file_name = str_random(25).".".$image->getClientOriginalExtension();
|
||||
$path = public_path('uploads/companies/'.$file_name);
|
||||
Image::make($image->getRealPath())->resize(200, null, function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
})->save($path);
|
||||
$file_name = $company->id.'-'.str_slug($image->getClientOriginalName()) . "." . $image->getClientOriginalExtension();
|
||||
|
||||
if ($image->getClientOriginalExtension()!='svg') {
|
||||
Image::make($image->getRealPath())->resize(500, null, function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
})->save(app('companies_upload_path').$file_name);
|
||||
} else {
|
||||
$image->move(app('companies_upload_path'), $file_name);
|
||||
}
|
||||
$company->image = $file_name;
|
||||
} elseif ($request->input('image_delete')=='1') {
|
||||
$company->image = null;
|
||||
|
||||
}
|
||||
|
||||
if ((($request->file('image')) && (isset($old_image)) && ($old_image!='')) || ($request->input('image_delete') == 1)) {
|
||||
try {
|
||||
unlink(app('companies_upload_path').$old_image);
|
||||
} catch (\Exception $e) {
|
||||
\Log::error($e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ namespace App\Http\Controllers;
|
||||
|
||||
use App\Helpers\Helper;
|
||||
use App\Http\Requests\ImageUploadRequest;
|
||||
use App\Models\Actionlog;
|
||||
use App\Models\Company;
|
||||
use App\Models\Component;
|
||||
use App\Models\CustomField;
|
||||
@@ -313,5 +314,97 @@ class ComponentsController extends Controller
|
||||
return redirect()->route('components.index')->with('success', trans('admin/components/message.checkout.success'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a view that allows the checkin of a component from an asset.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see ComponentsController::postCheckout() method that stores the data.
|
||||
* @since [v4.1.4]
|
||||
* @param int $componentId
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function getCheckin($component_asset_id)
|
||||
{
|
||||
|
||||
// This could probably be done more cleanly but I am very tired. - @snipe
|
||||
if ($component_assets = DB::table('components_assets')->find($component_asset_id)) {
|
||||
if (is_null($component = Component::find($component_assets->component_id))) {
|
||||
return redirect()->route('components.index')->with('error', trans('admin/components/messages.not_found'));
|
||||
}
|
||||
if (is_null($asset = Asset::find($component_assets->asset_id))) {
|
||||
return redirect()->route('components.index')->with('error',
|
||||
trans('admin/components/message.not_found'));
|
||||
}
|
||||
$this->authorize('checkin', $component_assets);
|
||||
return view('components/checkin', compact('component_assets','component','asset'));
|
||||
}
|
||||
|
||||
return redirect()->route('components.index')->with('error', trans('admin/components/messages.not_found'));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate and store checkin data.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see ComponentsController::getCheckout() method that returns the form.
|
||||
* @since [v4.1.4]
|
||||
* @param Request $request
|
||||
* @param int $componentId
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function postCheckin(Request $request, $component_asset_id)
|
||||
{
|
||||
if ($component_assets = DB::table('components_assets')->find($component_asset_id)) {
|
||||
if (is_null($component = Component::find($component_assets->component_id))) {
|
||||
return redirect()->route('components.index')->with('error',
|
||||
trans('admin/components/message.not_found'));
|
||||
}
|
||||
|
||||
|
||||
$this->authorize('checkin', $component);
|
||||
|
||||
$max_to_checkin = $component_assets->assigned_qty;
|
||||
$validator = Validator::make($request->all(), [
|
||||
"checkin_qty" => "required|numeric|between:1,$max_to_checkin"
|
||||
]);
|
||||
|
||||
if ($validator->fails()) {
|
||||
return redirect()->back()
|
||||
->withErrors($validator)
|
||||
->withInput();
|
||||
}
|
||||
|
||||
// Validation passed, so let's figure out what we have to do here.
|
||||
$qty_remaining_in_checkout = ($component_assets->assigned_qty - (int)$request->input('checkin_qty'));
|
||||
|
||||
// We have to modify the record to reflect the new qty that's
|
||||
// actually checked out.
|
||||
$component_assets->assigned_qty = $qty_remaining_in_checkout;
|
||||
DB::table('components_assets')->where('id',
|
||||
$component_asset_id)->update(['assigned_qty' => $qty_remaining_in_checkout]);
|
||||
|
||||
$log = new Actionlog();
|
||||
$log->user_id = Auth::user()->id;
|
||||
$log->action_type = 'checkin from';
|
||||
$log->target_type = Asset::class;
|
||||
$log->target_id = $component_assets->asset_id;
|
||||
$log->item_id = $component_assets->component_id;
|
||||
$log->item_type = Component::class;
|
||||
$log->note = $request->input('note');
|
||||
$log->save();
|
||||
|
||||
// If the checked-in qty is exactly the same as the assigned_qty,
|
||||
// we can simply delete the associated components_assets record
|
||||
if ($qty_remaining_in_checkout == 0) {
|
||||
DB::table('components_assets')->where('id', '=', $component_asset_id)->delete();
|
||||
}
|
||||
|
||||
return redirect()->route('components.index')->with('success',
|
||||
trans('admin/components/message.checkout.success'));
|
||||
}
|
||||
return redirect()->route('components.index')->with('error', trans('admin/components/message.not_found'));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Http\Requests\CustomFieldRequest;
|
||||
use View;
|
||||
use App\Models\CustomFieldset;
|
||||
use App\Models\CustomField;
|
||||
@@ -69,7 +70,7 @@ class CustomFieldsController extends Controller
|
||||
* @since [v1.8]
|
||||
* @return Redirect
|
||||
*/
|
||||
public function store(Request $request)
|
||||
public function store(CustomFieldRequest $request)
|
||||
{
|
||||
$field = new CustomField([
|
||||
"name" => $request->get("name"),
|
||||
@@ -81,27 +82,19 @@ class CustomFieldsController extends Controller
|
||||
]);
|
||||
|
||||
|
||||
|
||||
if (!in_array(Input::get('format'), array_keys(CustomField::$PredefinedFormats))) {
|
||||
$field->format = e($request->get("custom_format"));
|
||||
} else {
|
||||
$field->format = e($request->get("format"));
|
||||
}
|
||||
|
||||
|
||||
$validator = Validator::make(Input::all(), $field->rules);
|
||||
|
||||
if ($validator->passes()) {
|
||||
$results = $field->save();
|
||||
if ($results) {
|
||||
return redirect()->route("fields.index")->with("success", trans('admin/custom_fields/message.field.create.success'));
|
||||
} else {
|
||||
dd($field);
|
||||
return redirect()->back()->withInput()->with('error', trans('admin/custom_fields/message.field.create.error'));
|
||||
}
|
||||
if ($field->save()) {
|
||||
return redirect()->route("fields.index")->with("success", trans('admin/custom_fields/message.field.create.success'));
|
||||
} else {
|
||||
return redirect()->back()->withInput()->withErrors($validator);
|
||||
// dd($field);
|
||||
return redirect()->back()->withInput()->with('error', trans('admin/custom_fields/message.field.create.error'));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -169,7 +162,7 @@ class CustomFieldsController extends Controller
|
||||
* @since [v4.0]
|
||||
* @return Redirect
|
||||
*/
|
||||
public function update(Request $request, $id)
|
||||
public function update(CustomFieldRequest $request, $id)
|
||||
{
|
||||
$field = CustomField::find($id);
|
||||
|
||||
@@ -186,13 +179,12 @@ class CustomFieldsController extends Controller
|
||||
$field->format = e($request->get("format"));
|
||||
}
|
||||
|
||||
$validator = Validator::make(Input::all(), $field->rules);
|
||||
|
||||
if ($field->save()) {
|
||||
return redirect()->route("fields.index")->with("success", trans('admin/custom_fields/message.field.update.success'));
|
||||
}
|
||||
|
||||
return redirect()->back()->withInput()->withErrors($validator);
|
||||
return redirect()->back()->withInput()->with('error', trans('admin/custom_fields/message.field.update.error'));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -152,21 +152,38 @@ class DepartmentsController extends Controller
|
||||
}
|
||||
|
||||
$department->fill($request->all());
|
||||
$department->manager_id = ($request->has('manager_id' ) ? $request->input('manager_id') : null);
|
||||
|
||||
if ($request->file('image')) {
|
||||
$image = $request->file('image');
|
||||
$file_name = str_random(25).".".$image->getClientOriginalExtension();
|
||||
$path = public_path('uploads/departments/'.$file_name);
|
||||
Image::make($image->getRealPath())->resize(200, null, function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
})->save($path);
|
||||
$department->image = $file_name;
|
||||
} elseif ($request->input('image_delete')=='1') {
|
||||
$old_image = $department->image;
|
||||
|
||||
// Set the model's image property to null if the image is being deleted
|
||||
if ($request->input('image_delete') == 1) {
|
||||
$department->image = null;
|
||||
}
|
||||
|
||||
$department->manager_id = ($request->has('manager_id' ) ? $request->input('manager_id') : null);
|
||||
if ($request->file('image')) {
|
||||
$image = $request->file('image');
|
||||
$file_name = $department->id.'-'.str_slug($image->getClientOriginalName()) . "." . $image->getClientOriginalExtension();
|
||||
|
||||
if ($image->getClientOriginalExtension()!='svg') {
|
||||
Image::make($image->getRealPath())->resize(500, null, function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
})->save(app('departments_upload_path').$file_name);
|
||||
} else {
|
||||
$image->move(app('departments_upload_path'), $file_name);
|
||||
}
|
||||
$department->image = $file_name;
|
||||
|
||||
}
|
||||
|
||||
if ((($request->file('image')) && (isset($old_image)) && ($old_image!='')) || ($request->input('image_delete') == 1)) {
|
||||
try {
|
||||
unlink(app('departments_upload_path').$old_image);
|
||||
} catch (\Exception $e) {
|
||||
\Log::error($e);
|
||||
}
|
||||
}
|
||||
|
||||
if ($department->save()) {
|
||||
return redirect()->route("departments.index")->with('success', trans('admin/departments/message.update.success'));
|
||||
|
||||
@@ -239,16 +239,19 @@ class LicensesController extends Controller
|
||||
* @param int $seatId
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function getCheckout($seatId)
|
||||
public function getCheckout($licenceId)
|
||||
{
|
||||
// Check if the license seat exists
|
||||
if (is_null($licenseSeat = LicenseSeat::find($seatId))) {
|
||||
// Redirect to the asset management page with error
|
||||
return redirect()->route('licenses.index')->with('error', trans('admin/licenses/message.not_found'));
|
||||
// Check that the license is valid
|
||||
if ($license = License::where('id',$licenceId)->first()) {
|
||||
|
||||
// If the license is valid, check that there is an available seat
|
||||
if ($license->getAvailSeatsCountAttribute() < 1) {
|
||||
return redirect()->route('licenses.index')->with('error', 'There are no available seats for this license');
|
||||
}
|
||||
}
|
||||
|
||||
$this->authorize('checkout', $licenseSeat);
|
||||
return view('licenses/checkout', compact('licenseSeat'));
|
||||
$this->authorize('checkout', $license);
|
||||
return view('licenses/checkout', compact('license'));
|
||||
}
|
||||
|
||||
|
||||
@@ -262,78 +265,83 @@ class LicensesController extends Controller
|
||||
* @param int $seatId
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function postCheckout(Request $request, $seatId)
|
||||
public function postCheckout(Request $request, $licenseId)
|
||||
{
|
||||
$licenseSeat = LicenseSeat::find($seatId);
|
||||
$assigned_to = e($request->input('assigned_to'));
|
||||
$asset_id = e($request->input('asset_id'));
|
||||
|
||||
$this->authorize('checkout', $licenseSeat);
|
||||
// Check that the license is valid
|
||||
if ($license = License::where('id',$licenseId)->first()) {
|
||||
|
||||
// Declare the rules for the form validation
|
||||
$rules = [
|
||||
'note' => 'string|nullable',
|
||||
'asset_id' => 'required_without:assigned_to',
|
||||
];
|
||||
|
||||
// Create a new validator instance from our validation rules
|
||||
$validator = Validator::make(Input::all(), $rules);
|
||||
|
||||
// If validation fails, we'll exit the operation now.
|
||||
if ($validator->fails()) {
|
||||
// Ooops.. something went wrong
|
||||
return redirect()->back()->withInput()->withErrors($validator);
|
||||
}
|
||||
$target = null;
|
||||
if ($assigned_to!='') {
|
||||
// Check if the user exists
|
||||
if (is_null($target = User::find($assigned_to))) {
|
||||
// Redirect to the asset management page with error
|
||||
return redirect()->route('licenses.index')->with('error', trans('admin/licenses/message.user_does_not_exist'));
|
||||
}
|
||||
}
|
||||
|
||||
if ($asset_id!='') {
|
||||
if (is_null($target = Asset::find($asset_id))) {
|
||||
// Redirect to the asset management page with error
|
||||
return redirect()->route('licenses.index')->with('error', trans('admin/licenses/message.asset_does_not_exist'));
|
||||
// If the license is valid, check that there is an available seat
|
||||
if ($license->getAvailSeatsCountAttribute() < 1) {
|
||||
return redirect()->route('licenses.index')->with('error', 'There are no available seats for this license');
|
||||
}
|
||||
|
||||
if (($request->has('assigned_to')) && ($request->has('asset_id'))) {
|
||||
return redirect()->back()->withInput()->with('error', trans('admin/licenses/message.select_asset_or_person'));
|
||||
// Get the next available seat for this license
|
||||
$next = $license->freeSeat();
|
||||
|
||||
if (!$next) {
|
||||
return redirect()->route('licenses.index')->with('error', 'There are no available seats for this license');
|
||||
}
|
||||
|
||||
if (!$licenseSeat = LicenseSeat::where('id', '=', $next->id)->first()) {
|
||||
return redirect()->route('licenses.index')->with('error', 'There are no available seats for this license');
|
||||
}
|
||||
|
||||
|
||||
$this->authorize('checkout', $licenseSeat);
|
||||
|
||||
// Declare the rules for the form validation
|
||||
$rules = [
|
||||
'note' => 'string|nullable',
|
||||
'asset_id' => 'required_without:assigned_to',
|
||||
];
|
||||
|
||||
// Create a new validator instance from our validation rules
|
||||
$validator = Validator::make(Input::all(), $rules);
|
||||
|
||||
// If validation fails, we'll exit the operation now.
|
||||
if ($validator->fails()) {
|
||||
// Ooops.. something went wrong
|
||||
return redirect()->back()->withInput()->withErrors($validator);
|
||||
}
|
||||
$target = null;
|
||||
|
||||
|
||||
// This item is checked out to a an asset
|
||||
if (request('checkout_to_type')=='asset') {
|
||||
if (is_null($target = Asset::find(request('asset_id')))) {
|
||||
return redirect()->route('licenses.index')->with('error', trans('admin/licenses/message.asset_does_not_exist'));
|
||||
}
|
||||
$licenseSeat->asset_id = $request->input('asset_id');
|
||||
|
||||
// Override asset's assigned user if available
|
||||
if ($target->assigned_to!='') {
|
||||
$licenseSeat->assigned_to = $target->assigned_to;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// Fetch the target and set the license user
|
||||
if (is_null($target = User::find(request('assigned_to')))) {
|
||||
return redirect()->route('licenses.index')->with('error', trans('admin/licenses/message.user_does_not_exist'));
|
||||
}
|
||||
$licenseSeat->assigned_to = request('assigned_to');
|
||||
}
|
||||
|
||||
$licenseSeat->user_id = Auth::user()->id;
|
||||
|
||||
|
||||
if ($licenseSeat->save()) {
|
||||
$licenseSeat->logCheckout($request->input('note'), $target);
|
||||
return redirect()->route("licenses.index")->with('success', trans('admin/licenses/message.checkout.success'));
|
||||
}
|
||||
|
||||
}
|
||||
return redirect()->route('licenses.index')->with('error', trans('admin/licenses/message.not_found'));
|
||||
|
||||
// Check if the asset exists
|
||||
if (is_null($licenseSeat)) {
|
||||
// Redirect to the asset management page with error
|
||||
return redirect()->route('licenses.index')->with('error', trans('admin/licenses/message.not_found'));
|
||||
}
|
||||
|
||||
if ($request->input('asset_id') == '') {
|
||||
$licenseSeat->asset_id = null;
|
||||
} else {
|
||||
$licenseSeat->asset_id = $request->input('asset_id');
|
||||
}
|
||||
|
||||
// Update the asset data
|
||||
if ($request->input('assigned_to') == '') {
|
||||
$licenseSeat->assigned_to = null;
|
||||
} else {
|
||||
$licenseSeat->assigned_to = $request->input('assigned_to');
|
||||
}
|
||||
|
||||
// Was the asset updated?
|
||||
if ($licenseSeat->save()) {
|
||||
$licenseSeat->logCheckout($request->input('note'), $target);
|
||||
|
||||
$data['license_id'] = $licenseSeat->license_id;
|
||||
$data['note'] = $request->input('note');
|
||||
|
||||
// Redirect to the new asset page
|
||||
return redirect()->route("licenses.index")->with('success', trans('admin/licenses/message.checkout.success'));
|
||||
}
|
||||
|
||||
return redirect()->route("licenses.index")->with('error', trans('admin/licenses/message.checkout.error'));
|
||||
}
|
||||
|
||||
|
||||
@@ -204,17 +204,35 @@ class LocationsController extends Controller
|
||||
$location->ldap_ou = $request->input('ldap_ou');
|
||||
$location->manager_id = $request->input('manager_id');
|
||||
|
||||
$old_image = $location->image;
|
||||
|
||||
// Set the model's image property to null if the image is being deleted
|
||||
if ($request->input('image_delete') == 1) {
|
||||
$location->image = null;
|
||||
}
|
||||
|
||||
if ($request->file('image')) {
|
||||
$image = $request->file('image');
|
||||
$file_name = str_random(25).".".$image->getClientOriginalExtension();
|
||||
$path = public_path('uploads/locations/'.$file_name);
|
||||
Image::make($image->getRealPath())->resize(200, null, function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
})->save($path);
|
||||
$file_name = $location->id.'-'.str_slug($image->getClientOriginalName()) . "." . $image->getClientOriginalExtension();
|
||||
|
||||
if ($image->getClientOriginalExtension()!='svg') {
|
||||
Image::make($image->getRealPath())->resize(500, null, function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
})->save(app('locations_upload_path').$file_name);
|
||||
} else {
|
||||
$image->move(app('locations_upload_path'), $file_name);
|
||||
}
|
||||
$location->image = $file_name;
|
||||
} elseif ($request->input('image_delete')=='1') {
|
||||
$location->image = null;
|
||||
|
||||
}
|
||||
|
||||
if ((($request->file('image')) && (isset($old_image)) && ($old_image!='')) || ($request->input('image_delete') == 1)) {
|
||||
try {
|
||||
unlink(app('locations_upload_path').$old_image);
|
||||
} catch (\Exception $e) {
|
||||
\Log::error($e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -138,26 +138,35 @@ class ManufacturersController extends Controller
|
||||
$manufacturer->support_phone = $request->input('support_phone');
|
||||
$manufacturer->support_email = $request->input('support_email');
|
||||
|
||||
$old_image = $manufacturer->image;
|
||||
|
||||
// Set the model's image property to null if the image is being deleted
|
||||
if ($request->input('image_delete') == 1) {
|
||||
$manufacturer->image = null;
|
||||
}
|
||||
|
||||
if ($request->file('image')) {
|
||||
$image = $request->file('image');
|
||||
$file_name = str_slug($image->getClientOriginalName()).".".$image->getClientOriginalExtension();
|
||||
$path = public_path('uploads/manufacturers/'.$file_name);
|
||||
$old_image = $path.$manufacturer->image;
|
||||
$file_name = $manufacturer->id.'-'.str_slug($image->getClientOriginalName()) . "." . $image->getClientOriginalExtension();
|
||||
|
||||
if ($image->getClientOriginalExtension()!='svg') {
|
||||
Image::make($image->getRealPath())->resize(500, null, function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
})->save(app('manufacturers_upload_path').$file_name);
|
||||
} else {
|
||||
$image->move(app('manufacturers_upload_path'), $file_name);
|
||||
}
|
||||
$manufacturer->image = $file_name;
|
||||
|
||||
}
|
||||
|
||||
if ((($request->file('image')) && (isset($old_image)) && ($old_image!='')) || ($request->input('image_delete') == 1)) {
|
||||
try {
|
||||
unlink($old_image);
|
||||
unlink(app('manufacturers_upload_path').$old_image);
|
||||
} catch (\Exception $e) {
|
||||
\Log::error($e);
|
||||
}
|
||||
|
||||
|
||||
Image::make($image->getRealPath())->resize(200, null, function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
})->save($path);
|
||||
$manufacturer->image = $file_name;
|
||||
} elseif ($request->input('image_delete')=='1') {
|
||||
$manufacturer->image = null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -108,12 +108,12 @@ class ProfileController extends Controller
|
||||
{
|
||||
|
||||
if (config('app.lock_passwords')) {
|
||||
return redirect()->route('account.password.index')->with('error', Lang::get('admin/users/table.lock_passwords'));
|
||||
return redirect()->route('account.password.index')->with('error', trans('admin/users/table.lock_passwords'));
|
||||
}
|
||||
|
||||
$user = Auth::user();
|
||||
if ($user->ldap_import=='1') {
|
||||
return redirect()->route('account.password.index')->with('error', Lang::get('admin/users/message.error.password_ldap'));
|
||||
return redirect()->route('account.password.index')->with('error', trans('admin/users/message.error.password_ldap'));
|
||||
}
|
||||
|
||||
$rules = array(
|
||||
|
||||
@@ -156,6 +156,7 @@ class ReportsController extends Controller
|
||||
trans('admin/hardware/form.order'),
|
||||
trans('general.supplier'),
|
||||
trans('admin/hardware/table.checkoutto'),
|
||||
trans('general.type'),
|
||||
trans('admin/hardware/table.checkout_date'),
|
||||
trans('admin/hardware/table.location'),
|
||||
trans('general.notes'),
|
||||
@@ -166,6 +167,8 @@ class ReportsController extends Controller
|
||||
fputcsv($handle, $headers);
|
||||
|
||||
foreach ($assets as $asset) {
|
||||
|
||||
|
||||
// Add a new row with data
|
||||
$values=[
|
||||
($asset->company) ? $asset->company->name : '',
|
||||
@@ -175,14 +178,15 @@ class ReportsController extends Controller
|
||||
($asset->model->model_number) ? $asset->model->model_number : '',
|
||||
($asset->name) ? $asset->name : '',
|
||||
($asset->serial) ? $asset->serial : '',
|
||||
($asset->assetstatus) ? e($asset->assetstatus->name) : '',
|
||||
($asset->assetstatus) ? e($asset->present()->statusText) : '',
|
||||
($asset->purchase_date) ? e($asset->purchase_date) : '',
|
||||
($asset->purchase_cost > 0) ? Helper::formatCurrencyOutput($asset->purchase_cost) : '',
|
||||
($asset->order_number) ? e($asset->order_number) : '',
|
||||
($asset->supplier) ? e($asset->supplier->name) : '',
|
||||
($asset->assignedTo) ? e($asset->assignedTo->present()->name()) : '',
|
||||
($asset->checkedOutToUser() && $asset->assigned) ? e($asset->assigned->getFullNameAttribute()) : ($asset->assigned ? e($asset->assigned->display_name) : ''),
|
||||
($asset->checkedOutToUser() && $asset->assigned) ? 'user' : e($asset->assignedType()),
|
||||
($asset->last_checkout!='') ? e($asset->last_checkout) : '',
|
||||
($asset->location) ? e($asset->location->present()->name()) : '',
|
||||
($asset->location) ? e($asset->location->name) : '',
|
||||
($asset->notes) ? e($asset->notes) : '',
|
||||
];
|
||||
foreach ($customfields as $field) {
|
||||
@@ -582,7 +586,12 @@ class ReportsController extends Controller
|
||||
if (e(Input::get('username')) == '1') {
|
||||
// Only works if we're checked out to a user, not anything else.
|
||||
if ($asset->checkedOutToUser()) {
|
||||
$row[] = '"' .e($asset->assignedto->username). '"';
|
||||
if ($asset->assignedto) {
|
||||
$row[] = '"' .e($asset->assignedto->username). '"';
|
||||
} else {
|
||||
$row[] = ''; // Empty string if unassigned
|
||||
}
|
||||
|
||||
} else {
|
||||
$row[] = ''; // Empty string if unassigned
|
||||
}
|
||||
@@ -591,7 +600,12 @@ class ReportsController extends Controller
|
||||
if (e(Input::get('employee_num')) == '1') {
|
||||
// Only works if we're checked out to a user, not anything else.
|
||||
if ($asset->checkedOutToUser()) {
|
||||
$row[] = '"' .e($asset->assignedto->employee_num). '"';
|
||||
if ($asset->assignedto) {
|
||||
$row[] = '"' .e($asset->assignedto->employee_num). '"';
|
||||
} else {
|
||||
$row[] = ''; // Empty string if unassigned
|
||||
}
|
||||
|
||||
} else {
|
||||
$row[] = ''; // Empty string if unassigned
|
||||
}
|
||||
|
||||
@@ -552,6 +552,7 @@ class SettingsController extends Controller
|
||||
$setting->alert_threshold = $request->input('alert_threshold');
|
||||
$setting->audit_interval = $request->input('audit_interval');
|
||||
$setting->audit_warning_days = $request->input('audit_warning_days');
|
||||
$setting->show_alerts_in_menu = $request->input('show_alerts_in_menu', '0');
|
||||
|
||||
if ($setting->save()) {
|
||||
return redirect()->route('settings.index')
|
||||
@@ -747,6 +748,7 @@ class SettingsController extends Controller
|
||||
$setting->labels_fontsize = $request->input('labels_fontsize');
|
||||
$setting->labels_pagewidth = $request->input('labels_pagewidth');
|
||||
$setting->labels_pageheight = $request->input('labels_pageheight');
|
||||
$setting->labels_display_company_name = $request->input('labels_display_company_name', '0');
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -159,19 +159,38 @@ class SuppliersController extends Controller
|
||||
$supplier->notes = request('notes');
|
||||
|
||||
|
||||
if ($request->file('image')) {
|
||||
$image = $request->file('image');
|
||||
$file_name = str_random(25).".".$image->getClientOriginalExtension();
|
||||
$path = public_path('uploads/suppliers/'.$file_name);
|
||||
Image::make($image->getRealPath())->resize(200, null, function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
})->save($path);
|
||||
$supplier->image = $file_name;
|
||||
} elseif ($request->input('image_delete')=='1') {
|
||||
$old_image = $supplier->image;
|
||||
|
||||
// Set the model's image property to null if the image is being deleted
|
||||
if ($request->input('image_delete') == 1) {
|
||||
$supplier->image = null;
|
||||
}
|
||||
|
||||
if ($request->file('image')) {
|
||||
$image = $request->file('image');
|
||||
$file_name = $supplier->id.'-'.str_slug($image->getClientOriginalName()) . "." . $image->getClientOriginalExtension();
|
||||
|
||||
if ($image->getClientOriginalExtension()!='svg') {
|
||||
Image::make($image->getRealPath())->resize(500, null, function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
})->save(app('suppliers_upload_path').$file_name);
|
||||
} else {
|
||||
$image->move(app('suppliers_upload_path'), $file_name);
|
||||
}
|
||||
$supplier->image = $file_name;
|
||||
|
||||
}
|
||||
|
||||
if ((($request->file('image')) && (isset($old_image)) && ($old_image!='')) || ($request->input('image_delete') == 1)) {
|
||||
try {
|
||||
unlink(app('suppliers_upload_path').$old_image);
|
||||
} catch (\Exception $e) {
|
||||
\Log::error($e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ($supplier->save()) {
|
||||
return redirect()->route('suppliers.index')->with('success', trans('admin/suppliers/message.update.success'));
|
||||
}
|
||||
|
||||
@@ -106,7 +106,6 @@ class UsersController extends Controller
|
||||
$user->password = bcrypt($request->input('password'));
|
||||
$data['password'] = $request->input('password');
|
||||
}
|
||||
// Update the user
|
||||
$user->first_name = $request->input('first_name');
|
||||
$user->last_name = $request->input('last_name');
|
||||
$user->locale = $request->input('locale');
|
||||
@@ -278,6 +277,10 @@ class UsersController extends Controller
|
||||
try {
|
||||
|
||||
$user = User::find($id);
|
||||
|
||||
if ($user->id == $request->input('manager_id')) {
|
||||
return redirect()->back()->withInput()->with('error', 'You cannot be your own manager.');
|
||||
}
|
||||
$this->authorize('update', $user);
|
||||
// Figure out of this user was an admin before this edit
|
||||
$orig_permissions_array = $user->decodePermissions();
|
||||
|
||||
@@ -284,9 +284,10 @@ class ViewAssetsController extends Controller
|
||||
public function getAcceptAsset($logID = null)
|
||||
{
|
||||
|
||||
if (!$findlog = Actionlog::where('id', $logID)->first()) {
|
||||
echo 'no record';
|
||||
//return redirect()->to('account')->with('error', trans('admin/hardware/message.does_not_exist'));
|
||||
$findlog = Actionlog::where('id', $logID)->first();
|
||||
|
||||
if (!$findlog) {
|
||||
return redirect()->to('account/view-assets')->with('error', 'No matching record.');
|
||||
}
|
||||
|
||||
if ($findlog->accepted_id!='') {
|
||||
|
||||
@@ -24,9 +24,10 @@ class AssetCheckoutRequest extends Request
|
||||
public function rules()
|
||||
{
|
||||
$rules = [
|
||||
"assigned_user" => 'required_without_all:assigned_asset,assigned_location',
|
||||
"assigned_asset" => 'required_without_all:assigned_user,assigned_location|different:'.$this->id,
|
||||
"assigned_location" => 'required_without_all:assigned_user,assigned_asset',
|
||||
"assigned_user" => 'required_without_all:assigned_asset,assigned_location',
|
||||
"assigned_asset" => 'required_without_all:assigned_user,assigned_location|different:'.$this->id,
|
||||
"assigned_location" => 'required_without_all:assigned_user,assigned_asset',
|
||||
"checkout_to_type" => 'required|in:asset,location,user'
|
||||
];
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class CustomFieldRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules(Request $request)
|
||||
{
|
||||
|
||||
$rules = [];
|
||||
|
||||
switch($this->method())
|
||||
{
|
||||
|
||||
// Brand new
|
||||
case 'POST':
|
||||
{
|
||||
$rules['name'] = "required|unique:custom_fields";
|
||||
break;
|
||||
}
|
||||
|
||||
// Save all fields
|
||||
case 'PUT':
|
||||
$rules['name'] = "required";
|
||||
break;
|
||||
|
||||
// Save only what's passed
|
||||
case 'PATCH':
|
||||
{
|
||||
$rules['name'] = "required";
|
||||
break;
|
||||
}
|
||||
|
||||
default:break;
|
||||
}
|
||||
|
||||
$rules['custom_format'] = 'valid_regex';
|
||||
|
||||
return $rules;
|
||||
}
|
||||
}
|
||||
@@ -28,7 +28,7 @@ class AssetModelsTransformer
|
||||
'id' => (int) $assetmodel->manufacturer->id,
|
||||
'name'=> e($assetmodel->manufacturer->name)
|
||||
] : null,
|
||||
'image' => ($assetmodel->image!='') ? url('/').'/uploads/models/'.e($assetmodel->image) : null,
|
||||
'image' => ($assetmodel->image!='') ? app('models_upload_url').e($assetmodel->image) : null,
|
||||
'model_number' => e($assetmodel->model_number),
|
||||
'depreciation' => ($assetmodel->depreciation) ? [
|
||||
'id' => (int) $assetmodel->depreciation->id,
|
||||
|
||||
@@ -86,24 +86,21 @@ class AssetsTransformer
|
||||
$decrypted = \App\Helpers\Helper::gracefulDecrypt($field,$asset->{$field->convertUnicodeDbSlug()});
|
||||
$value = (Gate::allows('superadmin')) ? $decrypted : strtoupper(trans('admin/custom_fields/general.encrypted'));
|
||||
|
||||
// $fields_array = [$field->convertUnicodeDbSlug() => $value];
|
||||
|
||||
|
||||
$fields_array[$field->name] = [
|
||||
'field' => $field->convertUnicodeDbSlug(),
|
||||
'value' => $value
|
||||
'value' => $value,
|
||||
'field_format' => $field->format,
|
||||
];
|
||||
|
||||
} else {
|
||||
$fields_array[$field->name] = [
|
||||
'field' => $field->convertUnicodeDbSlug(),
|
||||
'value' => $asset->{$field->convertUnicodeDbSlug()}
|
||||
'value' => $asset->{$field->convertUnicodeDbSlug()},
|
||||
'field_format' => $field->format,
|
||||
];
|
||||
//$fields_array = [$field->convertUnicodeDbSlug() => $asset->{$field->convertUnicodeDbSlug()}];
|
||||
|
||||
|
||||
}
|
||||
//array += $fields_array;
|
||||
$array['custom_fields'] = $fields_array;
|
||||
}
|
||||
} else {
|
||||
@@ -114,10 +111,23 @@ class AssetsTransformer
|
||||
'checkout' => (bool) Gate::allows('checkout', Asset::class),
|
||||
'checkin' => (bool) Gate::allows('checkin', Asset::class),
|
||||
'clone' => Gate::allows('create', Asset::class) ? true : false,
|
||||
'restore' => false,
|
||||
'update' => (bool) Gate::allows('update', Asset::class),
|
||||
'delete' => (bool) Gate::allows('delete', Asset::class),
|
||||
];
|
||||
|
||||
if ($asset->deleted_at!='') {
|
||||
$permissions_array['available_actions'] = [
|
||||
'checkout' => true,
|
||||
'checkin' => false,
|
||||
'clone' => Gate::allows('create', Asset::class) ? true : false,
|
||||
'restore' => Gate::allows('create', Asset::class) ? true : false,
|
||||
'update' => false,
|
||||
'delete' => false,
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
$array += $permissions_array;
|
||||
return $array;
|
||||
}
|
||||
|
||||
@@ -25,8 +25,8 @@ class CategoriesTransformer
|
||||
$array = [
|
||||
'id' => (int) $category->id,
|
||||
'name' => e($category->name),
|
||||
'image' => ($category->image) ? e(url('/').'/uploads/categories/'.e($category->image)) : null,
|
||||
'type' => e($category->category_type),
|
||||
'image' => ($category->image) ? app('categories_upload_url').e($category->image) : null,
|
||||
'category_type' => e($category->category_type),
|
||||
'eula' => ($category->getEula()) ? true : false,
|
||||
'checkin_email' => ($category->checkin_email =='1') ? true : false,
|
||||
'require_acceptance' => ($category->require_acceptance =='1') ? true : false,
|
||||
|
||||
@@ -25,7 +25,7 @@ class CompaniesTransformer
|
||||
$array = [
|
||||
'id' => (int) $company->id,
|
||||
'name' => e($company->name),
|
||||
'image' => ($company->image) ? e(url('/').'/uploads/companies/'.e($company->image)) : null,
|
||||
'image' => ($company->image) ? app('companies_upload_url').e($company->image) : null,
|
||||
"created_at" => Helper::getFormattedDateObject($company->created_at, 'datetime'),
|
||||
"updated_at" => Helper::getFormattedDateObject($company->updated_at, 'datetime'),
|
||||
"assets_count" => (int) $company->assets_count,
|
||||
|
||||
@@ -25,7 +25,7 @@ class DepartmentsTransformer
|
||||
$array = [
|
||||
'id' => (int) $department->id,
|
||||
'name' => e($department->name),
|
||||
'image' => ($department->image) ? e(url('/').'/uploads/departments/'.e($department->image)) : null,
|
||||
'image' => ($department->image) ? app('departments_upload_url').e($department->image) : null,
|
||||
'company' => ($department->company) ? [
|
||||
'id' => (int) $department->company->id,
|
||||
'name'=> e($department->company->name)
|
||||
|
||||
@@ -30,20 +30,17 @@ class LicensesTransformer
|
||||
'purchase_order' => e($license->purchase_order),
|
||||
'purchase_date' => Helper::getFormattedDateObject($license->purchase_date, 'date'),
|
||||
'purchase_cost' => e($license->purchase_cost),
|
||||
'depreciation' => ($license->depreciation) ? ['id' => (int) $license->depreciation->id,'name'=> e($license->depreciation->name)] : null,
|
||||
'notes' => e($license->notes),
|
||||
'expiration_date' => Helper::getFormattedDateObject($license->expiration_date, 'date'),
|
||||
'total_seats' => (int) $license->seats,
|
||||
'next_seat' => ($license->freeSeat()) ? (int) $license->freeSeat()->id : null,
|
||||
'remaining_qty' => (int) $license->remaincount(),
|
||||
'min_qty' => $license->remaincount(),
|
||||
'seats' => (int) $license->seats,
|
||||
'free_seats_count' => (int) $license->free_seats_count,
|
||||
'license_name' => e($license->license_name),
|
||||
'license_email' => e($license->license_email),
|
||||
'maintained' => ($license->maintained == 1) ? true : false,
|
||||
'supplier' => ($license->supplier) ? ['id' => (int) $license->supplier->id,'name'=> e($license->supplier->name)] : null,
|
||||
'created_at' => Helper::getFormattedDateObject($license->created_at, 'datetime'),
|
||||
'updated_at' => Helper::getFormattedDateObject($license->updated_at, 'datetime'),
|
||||
'user_can_checkout' => (bool) ($license->remaincount() > 0),
|
||||
'user_can_checkout' => (bool) ($license->free_seats_count > 0),
|
||||
];
|
||||
|
||||
$permissions_array['available_actions'] = [
|
||||
|
||||
@@ -33,14 +33,14 @@ class LocationsTransformer
|
||||
$array = [
|
||||
'id' => (int) $location->id,
|
||||
'name' => e($location->name),
|
||||
'image' => ($location->image) ? e(url('/').'/uploads/locations/'.e($location->image)) : null,
|
||||
'image' => ($location->image) ? app('locations_upload_url').e($location->image) : null,
|
||||
'address' => e($location->address),
|
||||
'city' => e($location->city),
|
||||
'state' => e($location->state),
|
||||
'country' => e($location->country),
|
||||
'zip' => e($location->zip),
|
||||
'assets_count' => (int) $location->assets_count,
|
||||
'rtd_assets_count' => (int) $location->rtd_assets_count,
|
||||
'assigned_assets_count' => (int) $location->assigned_assets_count,
|
||||
'assets_count' => (int) $location->assets_count,
|
||||
'users_count' => (int) $location->users_count,
|
||||
|
||||
'created_at' => Helper::getFormattedDateObject($location->created_at, 'datetime'),
|
||||
|
||||
@@ -26,7 +26,7 @@ class ManufacturersTransformer
|
||||
'id' => (int) $manufacturer->id,
|
||||
'name' => e($manufacturer->name),
|
||||
'url' => e($manufacturer->url),
|
||||
'image' => ($manufacturer->image) ? e(url('/').'/uploads/manufacturers/'.e($manufacturer->image)) : null,
|
||||
'image' => ($manufacturer->image) ? app('manufacturers_upload_url').e($manufacturer->image) : null,
|
||||
'support_url' => e($manufacturer->support_url),
|
||||
'support_phone' => e($manufacturer->support_phone),
|
||||
'support_email' => e($manufacturer->support_email),
|
||||
|
||||
@@ -19,7 +19,7 @@ class SelectlistTransformer
|
||||
|
||||
public function transformSelectlist (LengthAwarePaginator $select_items)
|
||||
{
|
||||
$items_array = [];
|
||||
$items_array=[];
|
||||
|
||||
// Loop through the paginated collection to set the array values
|
||||
foreach ($select_items as $select_item) {
|
||||
@@ -32,6 +32,12 @@ class SelectlistTransformer
|
||||
|
||||
}
|
||||
|
||||
// This is weird and awful, but the only way I can find to allow the user to
|
||||
// clear the selection - @snipe
|
||||
if (count($items_array) > 0) {
|
||||
array_unshift($items_array, ['id' =>'', 'text'=> trans('general.clear_selection')]);
|
||||
}
|
||||
|
||||
$results = [
|
||||
'items' => $items_array,
|
||||
'pagination' =>
|
||||
|
||||
@@ -25,7 +25,7 @@ class SuppliersTransformer
|
||||
$array = [
|
||||
'id' => (int) $supplier->id,
|
||||
'name' => e($supplier->name),
|
||||
'image' => ($supplier->image) ? e(url('/').'/uploads/suppliers/'.e($supplier->image)) : null,
|
||||
'image' => ($supplier->image) ? app('suppliers_upload_url').e($supplier->image) : null,
|
||||
'address' => ($supplier->address) ? e($supplier->address) : null,
|
||||
'address2' => ($supplier->address2) ? e($supplier->address2) : null,
|
||||
'city' => ($supplier->city) ? e($supplier->city) : null,
|
||||
|
||||
@@ -31,7 +31,9 @@ class AssetImporter extends ItemImporter
|
||||
$this->item['custom_fields'][$customField->db_column_name()] = $customFieldValue;
|
||||
$this->log('Custom Field '. $customField->name.': '.$customFieldValue);
|
||||
} else {
|
||||
$this->item['custom_fields'][$customField->db_column_name()] = '';
|
||||
// This removes custom fields when updating if the column doesn't exist in file.
|
||||
// Commented out becausee not sure if it's needed anywhere.
|
||||
// $this->item['custom_fields'][$customField->db_column_name()] = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -77,17 +79,20 @@ class AssetImporter extends ItemImporter
|
||||
}
|
||||
|
||||
$this->item['asset_tag'] = $asset_tag;
|
||||
// By default we're set this to location_id in the item.
|
||||
$item = $this->sanitizeItemForStoring($asset, $editingAsset);
|
||||
// By default we're set this to location_id in the item.
|
||||
if (isset($this->item["location_id"])) {
|
||||
$item['rtd_location_id'] = $this->item['location_id'];
|
||||
unset($item['location_id']);
|
||||
}
|
||||
|
||||
if ($editingAsset) {
|
||||
$asset->update($item);
|
||||
} else {
|
||||
$asset->fill($item);
|
||||
}
|
||||
// If we're updating, we don't want to overwrite old fields.
|
||||
|
||||
if (array_key_exists('custom_fields', $this->item)) {
|
||||
foreach ($this->item['custom_fields'] as $custom_field => $val) {
|
||||
$asset->{$custom_field} = $val;
|
||||
|
||||
@@ -40,6 +40,7 @@ class ConsumableImporter extends ItemImporter
|
||||
$this->log("No matching consumable, creating one");
|
||||
$consumable = new Consumable();
|
||||
$consumable->fill($this->sanitizeItemForStoring($consumable));
|
||||
|
||||
if ($consumable->save()) {
|
||||
$consumable->logCreate('Imported using CSV Importer');
|
||||
$this->log("Consumable " . $this->item["name"] . ' was created');
|
||||
|
||||
@@ -63,7 +63,7 @@ class ItemImporter extends Importer
|
||||
$this->item["qty"] = $this->findCsvMatch($row, "quantity");
|
||||
$this->item["requestable"] = $this->findCsvMatch($row, "requestable");
|
||||
$this->item["user_id"] = $this->user_id;
|
||||
$this->item['serial'] = $this->findCsvMatch($row, "serial_number");
|
||||
$this->item['serial'] = $this->findCsvMatch($row, "serial");
|
||||
// NO need to call this method if we're running the user import.
|
||||
// TODO: Merge these methods.
|
||||
if(get_class($this) !== UserImporter::class) {
|
||||
@@ -92,6 +92,7 @@ class ItemImporter extends Importer
|
||||
$item = collect($this->item);
|
||||
// First Filter the item down to the model's fillable fields
|
||||
$item = $item->only($model->getFillable());
|
||||
|
||||
// Then iterate through the item and, if we are updating, remove any blank values.
|
||||
if ($updating) {
|
||||
$item = $item->reject(function ($value) {
|
||||
|
||||
@@ -17,7 +17,7 @@ class Accessory extends SnipeModel
|
||||
use Loggable, Presentable;
|
||||
use SoftDeletes;
|
||||
|
||||
protected $dates = ['deleted_at'];
|
||||
protected $dates = ['deleted_at', 'purchase_date'];
|
||||
protected $table = 'accessories';
|
||||
protected $casts = [
|
||||
'requestable' => 'boolean'
|
||||
|
||||
+87
-32
@@ -42,6 +42,7 @@ class Asset extends Depreciable
|
||||
*/
|
||||
protected $injectUniqueIdentifier = true;
|
||||
|
||||
// We set these as protected dates so that they will be easily accessible via Carbon
|
||||
protected $dates = [
|
||||
'created_at',
|
||||
'updated_at',
|
||||
@@ -138,13 +139,13 @@ class Asset extends Depreciable
|
||||
* @param User $user
|
||||
* @param User $admin
|
||||
* @param Carbon $checkout_at
|
||||
* @param null $expected_checkin
|
||||
* @param Carbon $expected_checkin
|
||||
* @param string $note
|
||||
* @param null $name
|
||||
* @return bool
|
||||
*/
|
||||
//FIXME: The admin parameter is never used. Can probably be removed.
|
||||
public function checkOut($target, $admin = null, $checkout_at = null, $expected_checkin = null, $note = null, $name = null)
|
||||
public function checkOut($target, $admin = null, $checkout_at = null, $expected_checkin = null, $note = null, $name = null, $location = null)
|
||||
{
|
||||
if (!$target) {
|
||||
return false;
|
||||
@@ -163,6 +164,10 @@ class Asset extends Depreciable
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
if ($location != null) {
|
||||
$this->location_id = $location;
|
||||
}
|
||||
|
||||
if ($this->requireAcceptance()) {
|
||||
if(get_class($target) != User::class) {
|
||||
throw new CheckoutNotAllowed;
|
||||
@@ -690,7 +695,7 @@ class Asset extends Depreciable
|
||||
|
||||
public function scopeDeleted($query)
|
||||
{
|
||||
return $query->whereNotNull('deleted_at');
|
||||
return $query->whereNotNull('assets.deleted_at');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -706,7 +711,7 @@ class Asset extends Depreciable
|
||||
*/
|
||||
public function scopeInModelList($query, array $modelIdListing)
|
||||
{
|
||||
return $query->whereIn('model_id', $modelIdListing);
|
||||
return $query->whereIn('assets.model_id', $modelIdListing);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -760,11 +765,11 @@ class Asset extends Depreciable
|
||||
{
|
||||
$search = explode(' OR ', $search);
|
||||
|
||||
return $query->leftJoin('users',function ($leftJoin) {
|
||||
$leftJoin->on("users.id", "=", "assets.assigned_to")
|
||||
return $query->leftJoin('users as assets_users',function ($leftJoin) {
|
||||
$leftJoin->on("assets_users.id", "=", "assets.assigned_to")
|
||||
->where("assets.assigned_type", "=", User::class);
|
||||
})->leftJoin('locations',function ($leftJoin) {
|
||||
$leftJoin->on("locations.id","=","assets.assigned_to")
|
||||
})->leftJoin('locations as assets_locations',function ($leftJoin) {
|
||||
$leftJoin->on("assets_locations.id","=","assets.assigned_to")
|
||||
->where("assets.assigned_type","=",Location::class);
|
||||
})->leftJoin('assets as assigned_assets',function ($leftJoin) {
|
||||
$leftJoin->on('assigned_assets.id', '=', 'assets.assigned_to')
|
||||
@@ -803,10 +808,10 @@ class Asset extends Depreciable
|
||||
$query->where('locations.name', 'LIKE', '%'.$search.'%');
|
||||
});
|
||||
})->orWhere(function ($query) use ($search) {
|
||||
$query->where('users.first_name', 'LIKE', '%'.$search.'%')
|
||||
->orWhere('users.last_name', 'LIKE', '%'.$search.'%')
|
||||
->orWhere('users.username', 'LIKE', '%'.$search.'%')
|
||||
->orWhere('locations.name', 'LIKE', '%'.$search.'%')
|
||||
$query->where('assets_users.first_name', 'LIKE', '%'.$search.'%')
|
||||
->orWhere('assets_users.last_name', 'LIKE', '%'.$search.'%')
|
||||
->orWhere('assets_users.username', 'LIKE', '%'.$search.'%')
|
||||
->orWhere('assets_locations.name', 'LIKE', '%'.$search.'%')
|
||||
->orWhere('assigned_assets.name', 'LIKE', '%'.$search.'%');
|
||||
})->orWhere('assets.name', 'LIKE', '%'.$search.'%')
|
||||
->orWhere('assets.asset_tag', 'LIKE', '%'.$search.'%')
|
||||
@@ -821,6 +826,62 @@ class Asset extends Depreciable
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Query builder scope to search on text for complex Bootstrap Tables API.
|
||||
*
|
||||
* @param \Illuminate\Database\Query\Builder $query Query builder instance
|
||||
* @param text $search Search term
|
||||
*
|
||||
* @return \Illuminate\Database\Query\Builder Modified query builder
|
||||
*/
|
||||
public function scopeAssignedSearch($query, $search)
|
||||
{
|
||||
$search = explode(' OR ', $search);
|
||||
|
||||
return $query->leftJoin('users as assets_users',function ($leftJoin) {
|
||||
$leftJoin->on("assets_users.id", "=", "assets.assigned_to")
|
||||
->where("assets.assigned_type", "=", User::class);
|
||||
})->leftJoin('locations as assets_locations',function ($leftJoin) {
|
||||
$leftJoin->on("assets_locations.id","=","assets.assigned_to")
|
||||
->where("assets.assigned_type","=",Location::class);
|
||||
})->leftJoin('assets as assigned_assets',function ($leftJoin) {
|
||||
$leftJoin->on('assigned_assets.id', '=', 'assets.assigned_to')
|
||||
->where('assets.assigned_type', '=', Asset::class);
|
||||
})->where(function ($query) use ($search) {
|
||||
foreach ($search as $search) {
|
||||
$query->whereHas('model', function ($query) use ($search) {
|
||||
$query->whereHas('category', function ($query) use ($search) {
|
||||
$query->where(function ($query) use ($search) {
|
||||
$query->where('categories.name', 'LIKE', '%'.$search.'%')
|
||||
->orWhere('models.name', 'LIKE', '%'.$search.'%')
|
||||
->orWhere('models.model_number', 'LIKE', '%'.$search.'%');
|
||||
});
|
||||
});
|
||||
})->orWhereHas('model', function ($query) use ($search) {
|
||||
$query->whereHas('manufacturer', function ($query) use ($search) {
|
||||
$query->where(function ($query) use ($search) {
|
||||
$query->where('manufacturers.name', 'LIKE', '%'.$search.'%');
|
||||
});
|
||||
});
|
||||
})->orWhere(function ($query) use ($search) {
|
||||
$query->where('assets_users.first_name', 'LIKE', '%'.$search.'%')
|
||||
->orWhere('assets_users.last_name', 'LIKE', '%'.$search.'%')
|
||||
->orWhere('assets_users.username', 'LIKE', '%'.$search.'%')
|
||||
->orWhere('assets_locations.name', 'LIKE', '%'.$search.'%')
|
||||
->orWhere('assigned_assets.name', 'LIKE', '%'.$search.'%');
|
||||
})->orWhere('assets.name', 'LIKE', '%'.$search.'%')
|
||||
->orWhere('assets.asset_tag', 'LIKE', '%'.$search.'%')
|
||||
->orWhere('assets.serial', 'LIKE', '%'.$search.'%')
|
||||
->orWhere('assets.order_number', 'LIKE', '%'.$search.'%')
|
||||
->orWhere('assets.notes', 'LIKE', '%'.$search.'%');
|
||||
}
|
||||
foreach (CustomField::all() as $field) {
|
||||
$query->orWhere('assets.'.$field->db_column_name(), 'LIKE', "%$search%");
|
||||
}
|
||||
})->withTrashed()->whereNull("assets.deleted_at"); //workaround for laravel bug
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Query builder scope to search on text filters for complex Bootstrap Tables API
|
||||
@@ -935,8 +996,9 @@ class Asset extends Depreciable
|
||||
}
|
||||
}
|
||||
|
||||
if (($fieldname!='category') && ($fieldname!='status_label')) {
|
||||
$query->orWhere('assets.'.$fieldname, 'LIKE', '%' . $search_val . '%');
|
||||
if (($fieldname!='category') && ($fieldname!='location')
|
||||
&& ($fieldname!='status_label') && ($fieldname!='model') && ($fieldname!='manufacturer')) {
|
||||
$query->orWhere('assets.'.$fieldname, 'LIKE', '%' . $search_val . '%');
|
||||
}
|
||||
|
||||
|
||||
@@ -957,7 +1019,7 @@ class Asset extends Depreciable
|
||||
*/
|
||||
public function scopeOrderModels($query, $order)
|
||||
{
|
||||
return $query->join('models', 'assets.model_id', '=', 'models.id')->orderBy('models.name', $order);
|
||||
return $query->join('models as asset_models', 'assets.model_id', '=', 'asset_models.id')->orderBy('asset_models.name', $order);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -984,7 +1046,7 @@ class Asset extends Depreciable
|
||||
*/
|
||||
public function scopeOrderAssigned($query, $order)
|
||||
{
|
||||
return $query->leftJoin('users', 'assets.assigned_to', '=', 'users.id')->select('assets.*')->orderBy('users.first_name', $order)->orderBy('users.last_name', $order);
|
||||
return $query->leftJoin('users as users_sort', 'assets.assigned_to', '=', 'users_sort.id')->select('assets.*')->orderBy('users_sort.first_name', $order)->orderBy('users_sort.last_name', $order);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -997,7 +1059,7 @@ class Asset extends Depreciable
|
||||
*/
|
||||
public function scopeOrderStatus($query, $order)
|
||||
{
|
||||
return $query->join('status_labels', 'assets.status_id', '=', 'status_labels.id')->orderBy('status_labels.name', $order);
|
||||
return $query->join('status_labels as status_sort', 'assets.status_id', '=', 'status_sort.id')->orderBy('status_sort.name', $order);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1010,7 +1072,7 @@ class Asset extends Depreciable
|
||||
*/
|
||||
public function scopeOrderCompany($query, $order)
|
||||
{
|
||||
return $query->leftJoin('companies', 'assets.company_id', '=', 'companies.id')->orderBy('companies.name', $order);
|
||||
return $query->leftJoin('companies as company_sort', 'assets.company_id', '=', 'company_sort.id')->orderBy('company_sort.name', $order);
|
||||
}
|
||||
|
||||
|
||||
@@ -1054,9 +1116,9 @@ class Asset extends Depreciable
|
||||
*/
|
||||
public function scopeOrderCategory($query, $order)
|
||||
{
|
||||
return $query->join('models', 'assets.model_id', '=', 'models.id')
|
||||
->join('categories', 'models.category_id', '=', 'categories.id')
|
||||
->orderBy('categories.name', $order);
|
||||
return $query->join('models as order_model_category', 'assets.model_id', '=', 'order_model_category.id')
|
||||
->join('categories as category_order', 'order_model_category.category_id', '=', 'category_order.id')
|
||||
->orderBy('category_order.name', $order);
|
||||
}
|
||||
|
||||
|
||||
@@ -1085,7 +1147,7 @@ class Asset extends Depreciable
|
||||
*/
|
||||
public function scopeOrderLocation($query, $order)
|
||||
{
|
||||
return $query->leftJoin('locations', 'locations.id', '=', 'assets.rtd_location_id')->orderBy('locations.name', $order);
|
||||
return $query->leftJoin('locations as asset_locations', 'asset_locations.id', '=', 'assets.location_id')->orderBy('asset_locations.name', $order);
|
||||
}
|
||||
|
||||
|
||||
@@ -1099,7 +1161,7 @@ class Asset extends Depreciable
|
||||
*/
|
||||
public function scopeOrderSupplier($query, $order)
|
||||
{
|
||||
return $query->leftJoin('suppliers', 'assets.supplier_id', '=', 'suppliers.id')->orderBy('suppliers.name', $order);
|
||||
return $query->leftJoin('suppliers as suppliers_assets', 'assets.supplier_id', '=', 'suppliers_assets.id')->orderBy('suppliers_assets.name', $order);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1113,18 +1175,11 @@ class Asset extends Depreciable
|
||||
public function scopeByLocationId($query, $search)
|
||||
{
|
||||
return $query->where(function ($query) use ($search) {
|
||||
$query->whereHas('defaultLoc', function ($query) use ($search) {
|
||||
$query->whereHas('location', function ($query) use ($search) {
|
||||
$query->where('locations.id', '=', $search);
|
||||
});
|
||||
});
|
||||
// FIXME: This needs porting to checkout to non-user.
|
||||
// ->orWhere(function ($query) use ($search) {
|
||||
// $query->whereHas('assigneduser', function ($query) use ($search) {
|
||||
// $query->whereHas('userloc', function ($query) use ($search) {
|
||||
// $query->where('locations.id', '=', $search);
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ class Component extends SnipeModel
|
||||
use Loggable, Presentable;
|
||||
use SoftDeletes;
|
||||
|
||||
protected $dates = ['deleted_at'];
|
||||
protected $dates = ['deleted_at', 'purchase_date'];
|
||||
protected $table = 'components';
|
||||
/**
|
||||
* Category validation rules
|
||||
|
||||
@@ -12,13 +12,14 @@ class Consumable extends SnipeModel
|
||||
use Loggable, Presentable;
|
||||
use SoftDeletes;
|
||||
|
||||
protected $dates = ['deleted_at'];
|
||||
protected $dates = ['deleted_at', 'purchase_date'];
|
||||
protected $table = 'consumables';
|
||||
protected $casts = [
|
||||
'requestable' => 'boolean'
|
||||
];
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Category validation rules
|
||||
*/
|
||||
|
||||
+76
-11
@@ -16,39 +16,73 @@ class CustomField extends Model
|
||||
public static $PredefinedFormats=[
|
||||
"ANY" => "",
|
||||
"ALPHA" => "alpha",
|
||||
"ALPHA-DASH" => "alpha_dash",
|
||||
"NUMERIC" => "numeric",
|
||||
"ALPHA-NUMERIC" => "alpha_num",
|
||||
"EMAIL" => "email",
|
||||
"DATE" => "date",
|
||||
"URL" => "url",
|
||||
"NUMERIC" => "numeric",
|
||||
"MAC" => "regex:/^[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}$/",
|
||||
"IP" => "ip",
|
||||
"IPV4" => "ipv4",
|
||||
"IPV6" => "ipv6",
|
||||
"MAC" => "regex:/^[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}$/",
|
||||
"BOOLEAN" => "boolean",
|
||||
];
|
||||
|
||||
public $rules = [
|
||||
"name" => "required|unique:custom_fields"
|
||||
"name" => "required|unique:custom_fields"
|
||||
];
|
||||
|
||||
public static $table_name="assets";
|
||||
// This is confusing, since it's actually the custom fields table that
|
||||
// we're usually modifying, but since we alter the assets table, we have to
|
||||
// say that here, otherwise the new fields get added onto the custom fields
|
||||
// table instead of the assets table.
|
||||
public static $table_name = "assets";
|
||||
|
||||
|
||||
/**
|
||||
* Convert the custom field's name property to a db-safe string.
|
||||
*
|
||||
* We could probably have used str_slug() here but not sure what it would
|
||||
* do with previously existing values. - @snipe
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v3.4]
|
||||
* @return String
|
||||
*/
|
||||
public static function name_to_db_name($name)
|
||||
{
|
||||
return "_snipeit_" . preg_replace("/[^a-zA-Z0-9]/", "_", strtolower($name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set some boot methods for creating and updating.
|
||||
*
|
||||
* There is never ever a time when we wouldn't want to be updating those asset
|
||||
* column names and the values of the db column name in the custom fields table
|
||||
* if they have changed, so we handle that here so that we don't have to remember
|
||||
* to do it in the controllers.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v3.4]
|
||||
* @return Boolean
|
||||
*/
|
||||
public static function boot()
|
||||
{
|
||||
self::created(function ($custom_field) {
|
||||
|
||||
|
||||
// column exists - nothing to do here
|
||||
// Column already exists on the assets table - nothing to do here.
|
||||
// This *shouldn't* happen in the wild.
|
||||
if (Schema::hasColumn(CustomField::$table_name, $custom_field->convertUnicodeDbSlug())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Update the column name in the assets table
|
||||
Schema::table(CustomField::$table_name, function ($table) use ($custom_field) {
|
||||
$table->text($custom_field->convertUnicodeDbSlug())->nullable();
|
||||
});
|
||||
|
||||
// Update the db_column property in the custom fields table
|
||||
$custom_field->db_column = $custom_field->convertUnicodeDbSlug();
|
||||
$custom_field->save();
|
||||
});
|
||||
@@ -56,20 +90,24 @@ class CustomField extends Model
|
||||
|
||||
self::updating(function ($custom_field) {
|
||||
|
||||
// Column already exists. Nothing to update.
|
||||
// Column already exists on the assets table - nothing to do here.
|
||||
if ($custom_field->isDirty("name")) {
|
||||
|
||||
if (Schema::hasColumn(CustomField::$table_name, $custom_field->convertUnicodeDbSlug())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// This is just a dumb thing we have to include because Laraval/Doctrine doesn't
|
||||
// play well with enums or a table that EVER had enums. :(
|
||||
$platform = Schema::getConnection()->getDoctrineSchemaManager()->getDatabasePlatform();
|
||||
$platform->registerDoctrineTypeMapping('enum', 'string');
|
||||
|
||||
|
||||
// Rename the field if the name has changed
|
||||
Schema::table(CustomField::$table_name, function ($table) use ($custom_field) {
|
||||
$table->renameColumn($custom_field->convertUnicodeDbSlug($custom_field->getOriginal("name")), $custom_field->convertUnicodeDbSlug());
|
||||
});
|
||||
|
||||
|
||||
// Save the updated column name to the custom fields table
|
||||
$custom_field->db_column = $custom_field->convertUnicodeDbSlug();
|
||||
$custom_field->save();
|
||||
|
||||
@@ -78,6 +116,8 @@ class CustomField extends Model
|
||||
return true;
|
||||
});
|
||||
|
||||
|
||||
// Drop the assets column if we've deleted it from custom fields
|
||||
self::deleting(function ($custom_field) {
|
||||
return Schema::table(CustomField::$table_name, function ($table) use ($custom_field) {
|
||||
$table->dropColumn($custom_field->convertUnicodeDbSlug());
|
||||
@@ -106,11 +146,21 @@ class CustomField extends Model
|
||||
return $this->db_column;
|
||||
}
|
||||
|
||||
// mutators for 'format' attribute
|
||||
/**
|
||||
* Mutator for the 'format' attribute.
|
||||
*
|
||||
* This is used by the dropdown to store the laravel-specific
|
||||
* validator strings in the database but still return the
|
||||
* user-friendly text in the dropdowns, and in the custom fields display.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v3.4]
|
||||
* @return Array
|
||||
*/
|
||||
public function getFormatAttribute($value)
|
||||
{
|
||||
foreach (self::$PredefinedFormats as $name => $pattern) {
|
||||
if ($pattern===$value) {
|
||||
if ($pattern === $value) {
|
||||
return $name;
|
||||
}
|
||||
}
|
||||
@@ -161,6 +211,13 @@ class CustomField extends Model
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the field is encrypted
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v3.4]
|
||||
* @return Boolean
|
||||
*/
|
||||
public function isFieldDecryptable($string)
|
||||
{
|
||||
if (($this->field_encrypted=='1') && ($string!='')) {
|
||||
@@ -170,6 +227,14 @@ class CustomField extends Model
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert non-UTF-8 or weirdly encoded text into something that
|
||||
* won't break the database.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v3.4]
|
||||
* @return Boolean
|
||||
*/
|
||||
public function convertUnicodeDbSlug($original = null)
|
||||
{
|
||||
$name = $original ? $original : $this->name;
|
||||
|
||||
+26
-5
@@ -22,7 +22,14 @@ class License extends Depreciable
|
||||
protected $injectUniqueIdentifier = true;
|
||||
use ValidatingTrait;
|
||||
|
||||
protected $dates = ['deleted_at'];
|
||||
// We set these as protected dates so that they will be easily accessible via Carbon
|
||||
protected $dates = [
|
||||
'created_at',
|
||||
'updated_at',
|
||||
'deleted_at',
|
||||
'purchase_date'
|
||||
];
|
||||
|
||||
|
||||
public $timestamps = true;
|
||||
|
||||
@@ -266,7 +273,9 @@ class License extends Depreciable
|
||||
public function availCount()
|
||||
{
|
||||
return $this->licenseSeatsRelation()
|
||||
->whereNull('asset_id');
|
||||
->whereNull('asset_id')
|
||||
->whereNull('assigned_to')
|
||||
->whereNull('deleted_at');
|
||||
}
|
||||
|
||||
public function getAvailSeatsCountAttribute()
|
||||
@@ -338,13 +347,25 @@ class License extends Depreciable
|
||||
*/
|
||||
public function freeSeat()
|
||||
{
|
||||
return $this->licenseseats()
|
||||
return $this->licenseseats()
|
||||
->whereNull('deleted_at')
|
||||
->whereNull('assigned_to')
|
||||
->whereNull('asset_id')
|
||||
->where(function ($query) {
|
||||
$query->whereNull('assigned_to')
|
||||
->whereNull('asset_id');
|
||||
})
|
||||
->orderBy('id', 'asc')
|
||||
->first();
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the next available free seat - used by
|
||||
* the API to populate next_seat
|
||||
*/
|
||||
public function freeSeats()
|
||||
{
|
||||
return $this->hasMany('\App\Models\LicenseSeat')->whereNull('assigned_to')->whereNull('deleted_at')->whereNull('asset_id');
|
||||
}
|
||||
|
||||
public static function getExpiringLicenses($days = 60)
|
||||
{
|
||||
|
||||
|
||||
@@ -54,7 +54,12 @@ class Location extends SnipeModel
|
||||
|
||||
public function assets()
|
||||
{
|
||||
return $this->hasMany('\App\Models\Asset', 'location_id');
|
||||
return $this->hasMany('\App\Models\Asset', 'location_id')
|
||||
->whereHas('assetstatus', function ($query) {
|
||||
$query->where('status_labels.deployable', '=', 1)
|
||||
->orWhere('status_labels.pending', '=', 1)
|
||||
->orWhere('status_labels.archived', '=', 0);
|
||||
});
|
||||
}
|
||||
|
||||
public function rtd_assets()
|
||||
@@ -92,7 +97,6 @@ class Location extends SnipeModel
|
||||
public function assignedAssets()
|
||||
{
|
||||
return $this->morphMany('App\Models\Asset', 'assigned', 'assigned_type', 'assigned_to')->withTrashed();
|
||||
// return $this->hasMany('\App\Models\Asset', 'assigned_to')->withTrashed();
|
||||
}
|
||||
|
||||
public function setLdapOuAttribute($ldap_ou)
|
||||
|
||||
@@ -89,6 +89,18 @@ class Setting extends Model
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Escapes the custom CSS, and then un-escapes the greater-than symbol
|
||||
* so it can work with direct descendant characters for bootstrap
|
||||
* menu overrides like:
|
||||
*
|
||||
* .skin-blue .sidebar-menu>li.active>a, .skin-blue .sidebar-menu>li:hover>a
|
||||
*
|
||||
* Important: Do not remove the e() escaping here, as we output raw in the blade.
|
||||
*
|
||||
* @return string escaped CSS
|
||||
* @author A. Gianotto <snipe@snipe.net>
|
||||
*/
|
||||
public function show_custom_css()
|
||||
{
|
||||
$custom_css = Setting::getSettings()->custom_css;
|
||||
|
||||
@@ -24,6 +24,7 @@ class SnipeModel extends Model
|
||||
public function setPurchaseCostAttribute($value)
|
||||
{
|
||||
$value = Helper::ParseFloat($value);
|
||||
|
||||
if ($value == '0.0') {
|
||||
$value = null;
|
||||
}
|
||||
|
||||
+7
-6
@@ -61,7 +61,6 @@ class User extends SnipeModel implements AuthenticatableContract, CanResetPasswo
|
||||
'email' => 'email|nullable',
|
||||
'password' => 'required|min:6',
|
||||
'locale' => 'max:10|nullable',
|
||||
'manager_id' => 'nullable|different:id',
|
||||
];
|
||||
|
||||
|
||||
@@ -440,10 +439,12 @@ class User extends SnipeModel implements AuthenticatableContract, CanResetPasswo
|
||||
});
|
||||
})
|
||||
|
||||
// Ugly, ugly code because Laravel sucks at self-joins
|
||||
//Ugly, ugly code because Laravel sucks at self-joins
|
||||
->orWhere(function ($query) use ($search) {
|
||||
$query->whereRaw("users.manager_id IN (select id from users where first_name LIKE '%".$search."%' OR last_name LIKE '%".$search."%') ");
|
||||
$query->whereRaw("users.manager_id IN (select id from users where first_name LIKE ? OR last_name LIKE ?)", ["%$search%", "%$search%"]);
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
@@ -474,7 +475,7 @@ class User extends SnipeModel implements AuthenticatableContract, CanResetPasswo
|
||||
public function scopeOrderManager($query, $order)
|
||||
{
|
||||
// Left join here, or it will only return results with parents
|
||||
return $query->leftJoin('users as manager', 'users.manager_id', '=', 'manager.id')->orderBy('manager.first_name', $order)->orderBy('manager.last_name', $order);
|
||||
return $query->leftJoin('users as users_manager', 'users.manager_id', '=', 'users_manager.id')->orderBy('users_manager.first_name', $order)->orderBy('users_manager.last_name', $order);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -487,7 +488,7 @@ class User extends SnipeModel implements AuthenticatableContract, CanResetPasswo
|
||||
*/
|
||||
public function scopeOrderLocation($query, $order)
|
||||
{
|
||||
return $query->leftJoin('locations', 'users.location_id', '=', 'locations.id')->orderBy('locations.name', $order);
|
||||
return $query->leftJoin('locations as locations_users', 'users.location_id', '=', 'locations_users.id')->orderBy('locations_users.name', $order);
|
||||
}
|
||||
|
||||
|
||||
@@ -501,6 +502,6 @@ class User extends SnipeModel implements AuthenticatableContract, CanResetPasswo
|
||||
*/
|
||||
public function scopeOrderDepartment($query, $order)
|
||||
{
|
||||
return $query->leftJoin('departments', 'users.department_id', '=', 'departments.id')->orderBy('departments.name', $order);
|
||||
return $query->leftJoin('departments as departments_users', 'users.department_id', '=', 'departments_users.id')->orderBy('departments_users.name', $order);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@ class CheckoutNotification extends Notification
|
||||
'first_name' => $target->present()->fullName(),
|
||||
'item_name' => $item->present()->name(),
|
||||
'checkout_date' => $item->last_checkout,
|
||||
'expected_checkin' => $item->expected_checkin,
|
||||
'expected_checkin' => ($item->expected_checkin) ? $item->expected_checkin->format('Y-m-d') : '',
|
||||
'item_tag' => $item->asset_tag,
|
||||
'note' => $this->params['note'],
|
||||
'item_serial' => $item->serial,
|
||||
|
||||
@@ -26,7 +26,6 @@ abstract class SnipePermissionsPolicy
|
||||
|
||||
public function index(User $user)
|
||||
{
|
||||
// dd('here');
|
||||
return $user->hasAccess($this->columnName().'.view');
|
||||
}
|
||||
/**
|
||||
@@ -37,7 +36,6 @@ abstract class SnipePermissionsPolicy
|
||||
*/
|
||||
public function view(User $user, $item = null)
|
||||
{
|
||||
//
|
||||
return $user->hasAccess($this->columnName().'.view');
|
||||
}
|
||||
|
||||
@@ -49,7 +47,6 @@ abstract class SnipePermissionsPolicy
|
||||
*/
|
||||
public function create(User $user)
|
||||
{
|
||||
//
|
||||
return $user->hasAccess($this->columnName().'.create');
|
||||
}
|
||||
|
||||
@@ -61,7 +58,6 @@ abstract class SnipePermissionsPolicy
|
||||
*/
|
||||
public function update(User $user, $item = null)
|
||||
{
|
||||
//
|
||||
return $user->hasAccess($this->columnName().'.edit');
|
||||
}
|
||||
|
||||
@@ -73,7 +69,6 @@ abstract class SnipePermissionsPolicy
|
||||
*/
|
||||
public function delete(User $user, $item = null)
|
||||
{
|
||||
//
|
||||
return $user->hasAccess($this->columnName().'.delete');
|
||||
}
|
||||
|
||||
|
||||
@@ -289,10 +289,8 @@ class AssetPresenter extends Presenter
|
||||
$imagePath = '';
|
||||
if ($this->image && !empty($this->image)) {
|
||||
$imagePath = $this->image;
|
||||
return 'poop';
|
||||
} elseif ($this->model && !empty($this->model->image)) {
|
||||
$imagePath = $this->model->image;
|
||||
return 'fart';
|
||||
}
|
||||
if (!empty($imagePath)) {
|
||||
return config('app.url').'/uploads/assets/'.$imagePath;
|
||||
|
||||
@@ -40,7 +40,7 @@ class CategoryPresenter extends Presenter
|
||||
"visible" => true,
|
||||
"formatter" => 'imageFormatter',
|
||||
],[
|
||||
"field" => "type",
|
||||
"field" => "category_type",
|
||||
"searchable" => true,
|
||||
"sortable" => true,
|
||||
"title" => trans('general.type'),
|
||||
|
||||
@@ -76,14 +76,14 @@ class LicensePresenter extends Presenter
|
||||
"title" => trans('general.manufacturer'),
|
||||
"formatter" => "manufacturersLinkObjFormatter",
|
||||
], [
|
||||
"field" => "total_seats",
|
||||
"field" => "seats",
|
||||
"searchable" => false,
|
||||
"sortable" => false,
|
||||
"sortable" => true,
|
||||
"title" => trans('admin/accessories/general.total'),
|
||||
], [
|
||||
"field" => "remaining_qty",
|
||||
"field" => "free_seats_count",
|
||||
"searchable" => false,
|
||||
"sortable" => false,
|
||||
"sortable" => true,
|
||||
"title" => trans('admin/accessories/general.remaining'),
|
||||
], [
|
||||
"field" => "purchase_date",
|
||||
|
||||
@@ -40,7 +40,7 @@ class LocationPresenter extends Presenter
|
||||
|
||||
public function glyph()
|
||||
{
|
||||
return '<i class="fa fa-globe"></i>';
|
||||
return '<i class="fa fa-map-marker"></i>';
|
||||
}
|
||||
|
||||
public function fullName() {
|
||||
|
||||
@@ -352,6 +352,6 @@ class UserPresenter extends Presenter
|
||||
|
||||
public function glyph()
|
||||
{
|
||||
return '<i class="fa fa-users"></i>';
|
||||
return '<i class="fa fa-user"></i>';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
<?php
|
||||
namespace App\Providers;
|
||||
|
||||
use Validator;
|
||||
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use DB;
|
||||
use Log;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use App\Observers\AssetObserver;
|
||||
@@ -19,7 +18,7 @@ use App\Models\Component;
|
||||
|
||||
|
||||
/**
|
||||
* This service provider handles a few custom validation rules.
|
||||
* This service provider handles setting the observers on models
|
||||
*
|
||||
* PHP version 5.5.9
|
||||
* @version v3.0
|
||||
@@ -42,47 +41,7 @@ class AppServiceProvider extends ServiceProvider
|
||||
Component::observe(ComponentObserver::class);
|
||||
Consumable::observe(ConsumableObserver::class);
|
||||
License::observe(LicenseObserver::class);
|
||||
|
||||
// Email array validator
|
||||
Validator::extend('email_array', function ($attribute, $value, $parameters, $validator) {
|
||||
$value = str_replace(' ', '', $value);
|
||||
$array = explode(',', $value);
|
||||
|
||||
foreach ($array as $email) { //loop over values
|
||||
$email_to_validate['alert_email'][]=$email;
|
||||
}
|
||||
|
||||
$rules = array('alert_email.*'=>'email');
|
||||
$messages = array(
|
||||
'alert_email.*'=>trans('validation.email_array')
|
||||
);
|
||||
|
||||
$validator = Validator::make($email_to_validate, $rules, $messages);
|
||||
|
||||
return $validator->passes();
|
||||
|
||||
});
|
||||
|
||||
// Unique only if undeleted
|
||||
// This works around the use case where multiple deleted items have the same unique attribute.
|
||||
// (I think this is a bug in Laravel's validator?)
|
||||
Validator::extend('unique_undeleted', function ($attribute, $value, $parameters, $validator) {
|
||||
|
||||
if (count($parameters)) {
|
||||
$count = DB::table($parameters[0])->select('id')->where($attribute, '=', $value)->whereNull('deleted_at')->where('id', '!=', $parameters[1])->count();
|
||||
return $count < 1;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// Share common setting variables with all views.
|
||||
view()->composer('*', function ($view) {
|
||||
$view->with('snipeSettings', \App\Models\Setting::getSettings());
|
||||
});
|
||||
|
||||
// Set the monetary locale to the configured locale to make helper::parseFloat work.
|
||||
setlocale(LC_MONETARY, config('app.locale'));
|
||||
setlocale(LC_NUMERIC, config('app.locale'));
|
||||
|
||||
}
|
||||
|
||||
@@ -97,7 +56,7 @@ class AppServiceProvider extends ServiceProvider
|
||||
$log_level = config('app.log_level');
|
||||
|
||||
if (($this->app->environment('production')) && (config('services.rollbar.access_token'))){
|
||||
$this->app->register(\Jenssegers\Rollbar\RollbarServiceProvider::class);
|
||||
$this->app->register(\Rollbar\Laravel\RollbarServiceProvider::class);
|
||||
}
|
||||
|
||||
foreach ($monolog->getHandlers() as $handler) {
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
<?php
|
||||
namespace App\Providers;
|
||||
|
||||
use Validator;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use DB;
|
||||
use Log;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This service provider handles sharing the snipeSettings variable, and sets
|
||||
* some common upload path and image urls.
|
||||
*
|
||||
* PHP version 5.5.9
|
||||
* @version v3.0
|
||||
*/
|
||||
|
||||
class SettingsServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Custom email array validation
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v3.0]
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
|
||||
|
||||
// Share common setting variables with all views.
|
||||
view()->composer('*', function ($view) {
|
||||
$view->with('snipeSettings', \App\Models\Setting::getSettings());
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Set some common variables so that they're globally available.
|
||||
* The paths should always be public (versus private uploads)
|
||||
*/
|
||||
// Model paths and URLs
|
||||
\App::singleton('models_upload_path', function(){
|
||||
return public_path('/uploads/models/');
|
||||
});
|
||||
|
||||
\App::singleton('models_upload_url', function(){
|
||||
return url('/').'/uploads/models/';
|
||||
});
|
||||
|
||||
// Categories
|
||||
\App::singleton('categories_upload_path', function(){
|
||||
return public_path('/uploads/categories/');
|
||||
});
|
||||
|
||||
\App::singleton('categories_upload_url', function(){
|
||||
return url('/').'/uploads/categories/';
|
||||
});
|
||||
|
||||
// Locations
|
||||
\App::singleton('locations_upload_path', function(){
|
||||
return public_path('/uploads/locations/');
|
||||
});
|
||||
|
||||
\App::singleton('locations_upload_url', function(){
|
||||
return url('/').'/uploads/locations/';
|
||||
});
|
||||
|
||||
// Users
|
||||
\App::singleton('users_upload_path', function(){
|
||||
return public_path('/uploads/users/');
|
||||
});
|
||||
|
||||
\App::singleton('users_upload_url', function(){
|
||||
return url('/').'/uploads/users/';
|
||||
});
|
||||
|
||||
// Manufacturers
|
||||
\App::singleton('manufacturers_upload_path', function(){
|
||||
return public_path('/uploads/manufacturers/');
|
||||
});
|
||||
|
||||
\App::singleton('manufacturers_upload_url', function(){
|
||||
return url('/').'/uploads/manufacturers/';
|
||||
});
|
||||
|
||||
// Suppliers
|
||||
\App::singleton('suppliers_upload_path', function(){
|
||||
return public_path('/uploads/suppliers/');
|
||||
});
|
||||
|
||||
\App::singleton('suppliers_upload_url', function(){
|
||||
return url('/').'/uploads/suppliers/';
|
||||
});
|
||||
|
||||
// Departments
|
||||
\App::singleton('departments_upload_path', function(){
|
||||
return public_path('/uploads/departments/');
|
||||
});
|
||||
|
||||
\App::singleton('departments_upload_url', function(){
|
||||
return url('/').'/uploads/departments/';
|
||||
});
|
||||
|
||||
// Company paths and URLs
|
||||
\App::singleton('companies_upload_path', function(){
|
||||
return public_path('/uploads/companies/');
|
||||
});
|
||||
|
||||
\App::singleton('companies_upload_url', function(){
|
||||
return url('/').'/uploads/companies/';
|
||||
});
|
||||
|
||||
|
||||
|
||||
// Set the monetary locale to the configured locale to make helper::parseFloat work.
|
||||
setlocale(LC_MONETARY, config('app.locale'));
|
||||
setlocale(LC_NUMERIC, config('app.locale'));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Register any application services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
<?php
|
||||
namespace App\Providers;
|
||||
|
||||
use Validator;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use DB;
|
||||
use Log;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use App\Observers\AssetObserver;
|
||||
use App\Observers\LicenseObserver;
|
||||
use App\Observers\AccessoryObserver;
|
||||
use App\Observers\ConsumableObserver;
|
||||
use App\Observers\ComponentObserver;
|
||||
use App\Models\Asset;
|
||||
use App\Models\License;
|
||||
use App\Models\Accessory;
|
||||
use App\Models\Consumable;
|
||||
use App\Models\Component;
|
||||
|
||||
|
||||
/**
|
||||
* This service provider handles a few custom validation rules.
|
||||
*
|
||||
* PHP version 5.5.9
|
||||
* @version v3.0
|
||||
*/
|
||||
|
||||
class ValidationServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Custom email array validation
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v3.0]
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
|
||||
// Email array validator
|
||||
Validator::extend('email_array', function ($attribute, $value, $parameters, $validator) {
|
||||
$value = str_replace(' ', '', $value);
|
||||
$array = explode(',', $value);
|
||||
|
||||
foreach ($array as $email) { //loop over values
|
||||
$email_to_validate['alert_email'][]=$email;
|
||||
}
|
||||
|
||||
$rules = array('alert_email.*'=>'email');
|
||||
$messages = array(
|
||||
'alert_email.*'=>trans('validation.email_array')
|
||||
);
|
||||
|
||||
$validator = Validator::make($email_to_validate, $rules, $messages);
|
||||
|
||||
return $validator->passes();
|
||||
|
||||
});
|
||||
|
||||
|
||||
// Unique only if undeleted
|
||||
// This works around the use case where multiple deleted items have the same unique attribute.
|
||||
// (I think this is a bug in Laravel's validator?)
|
||||
Validator::extend('unique_undeleted', function ($attribute, $value, $parameters, $validator) {
|
||||
|
||||
if (count($parameters)) {
|
||||
$count = DB::table($parameters[0])->select('id')->where($attribute, '=', $value)->whereNull('deleted_at')->where('id', '!=', $parameters[1])->count();
|
||||
return $count < 1;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
// Yo dawg. I heard you like validators.
|
||||
// This validates the custom validator regex in custom fields.
|
||||
// We're just checking that the regex won't throw an exception, not
|
||||
// that it's actually correct for what the user intended.
|
||||
|
||||
Validator::extend('valid_regex', function ($attribute, $value, $parameters, $validator) {
|
||||
|
||||
// Make sure it's not just an ANY format
|
||||
if ($value!='') {
|
||||
|
||||
// Check that the string starts with regex:
|
||||
if (strpos($value, 'regex:') === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$test_string = 'My hovercraft is full of eels';
|
||||
|
||||
// We have to stip out the regex: part here to check with preg_match
|
||||
$test_pattern = str_replace('regex:','', $value);
|
||||
|
||||
try {
|
||||
preg_match($test_pattern, $test_string);
|
||||
return true;
|
||||
} catch (\Exception $e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Register any application services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
+2
-3
@@ -4,9 +4,8 @@
|
||||
"keywords": ["assets", "asset-management", "laravel"],
|
||||
"license": "AGPL-3",
|
||||
"type": "project",
|
||||
"require": {
|
||||
"require": {
|
||||
"php": ">=5.6.4",
|
||||
"aws/aws-sdk-php-laravel": "^3.1",
|
||||
"barryvdh/laravel-debugbar": "^2.4",
|
||||
"doctrine/cache": "^1.6",
|
||||
"doctrine/common": "^2.7",
|
||||
@@ -17,7 +16,6 @@
|
||||
"fideloper/proxy": "^3.1",
|
||||
"intervention/image": "^2.3",
|
||||
"javiereguiluz/easyslugger": "^1.0",
|
||||
"jenssegers/rollbar": "^1.5",
|
||||
"laravel/framework": "5.4.29",
|
||||
"laravel/passport": "^3.0",
|
||||
"laravel/tinker": "^1.0",
|
||||
@@ -30,6 +28,7 @@
|
||||
"phpspec/prophecy": "1.6.2",
|
||||
"pragmarx/google2fa": "^1.0",
|
||||
"predis/predis": "^1.1",
|
||||
"rollbar/rollbar-laravel": "^2.2",
|
||||
"schuppo/password-strength": "~1.5",
|
||||
"spatie/laravel-backup": "^3.0.0",
|
||||
"tecnickcom/tc-lib-barcode": "^1.15",
|
||||
|
||||
Generated
+105
-271
@@ -4,144 +4,8 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "a1fc66ea043e149e85b4d708f852adbe",
|
||||
"content-hash": "53bd9d88d11d74732ab302b7ebd01af3",
|
||||
"packages": [
|
||||
{
|
||||
"name": "aws/aws-sdk-php",
|
||||
"version": "3.36.32",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/aws/aws-sdk-php.git",
|
||||
"reference": "7ba49dbd24366647a41cd4a13eab972b2264b8db"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/7ba49dbd24366647a41cd4a13eab972b2264b8db",
|
||||
"reference": "7ba49dbd24366647a41cd4a13eab972b2264b8db",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"ext-pcre": "*",
|
||||
"ext-simplexml": "*",
|
||||
"ext-spl": "*",
|
||||
"guzzlehttp/guzzle": "^5.3.1|^6.2.1",
|
||||
"guzzlehttp/promises": "~1.0",
|
||||
"guzzlehttp/psr7": "^1.4.1",
|
||||
"mtdowling/jmespath.php": "~2.2",
|
||||
"php": ">=5.5"
|
||||
},
|
||||
"require-dev": {
|
||||
"andrewsville/php-token-reflection": "^1.4",
|
||||
"aws/aws-php-sns-message-validator": "~1.0",
|
||||
"behat/behat": "~3.0",
|
||||
"doctrine/cache": "~1.4",
|
||||
"ext-dom": "*",
|
||||
"ext-openssl": "*",
|
||||
"nette/neon": "^2.3",
|
||||
"phpunit/phpunit": "^4.8.35|^5.4.0",
|
||||
"psr/cache": "^1.0"
|
||||
},
|
||||
"suggest": {
|
||||
"aws/aws-php-sns-message-validator": "To validate incoming SNS notifications",
|
||||
"doctrine/cache": "To use the DoctrineCacheAdapter",
|
||||
"ext-curl": "To send requests using cURL",
|
||||
"ext-openssl": "Allows working with CloudFront private distributions and verifying received SNS messages"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "3.0-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Aws\\": "src/"
|
||||
},
|
||||
"files": [
|
||||
"src/functions.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"Apache-2.0"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Amazon Web Services",
|
||||
"homepage": "http://aws.amazon.com"
|
||||
}
|
||||
],
|
||||
"description": "AWS SDK for PHP - Use Amazon Web Services in your PHP project",
|
||||
"homepage": "http://aws.amazon.com/sdkforphp",
|
||||
"keywords": [
|
||||
"amazon",
|
||||
"aws",
|
||||
"cloud",
|
||||
"dynamodb",
|
||||
"ec2",
|
||||
"glacier",
|
||||
"s3",
|
||||
"sdk"
|
||||
],
|
||||
"time": "2017-10-23T20:40:28+00:00"
|
||||
},
|
||||
{
|
||||
"name": "aws/aws-sdk-php-laravel",
|
||||
"version": "3.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/aws/aws-sdk-php-laravel.git",
|
||||
"reference": "3b946892d493b91b4920ec4facc4a0ad7195fb86"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/aws/aws-sdk-php-laravel/zipball/3b946892d493b91b4920ec4facc4a0ad7195fb86",
|
||||
"reference": "3b946892d493b91b4920ec4facc4a0ad7195fb86",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"aws/aws-sdk-php": "~3.0",
|
||||
"illuminate/support": "~5.1",
|
||||
"php": ">=5.5.9"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "~4.0|~5.0"
|
||||
},
|
||||
"suggest": {
|
||||
"laravel/framework": "To test the Laravel bindings",
|
||||
"laravel/lumen-framework": "To test the Lumen bindings"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Aws\\Laravel\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"Apache-2.0"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Amazon Web Services",
|
||||
"homepage": "http://aws.amazon.com"
|
||||
}
|
||||
],
|
||||
"description": "A simple Laravel 5 service provider for including the AWS SDK for PHP.",
|
||||
"homepage": "http://aws.amazon.com/sdkforphp2",
|
||||
"keywords": [
|
||||
"amazon",
|
||||
"aws",
|
||||
"dynamodb",
|
||||
"ec2",
|
||||
"laravel",
|
||||
"laravel 5",
|
||||
"s3",
|
||||
"sdk"
|
||||
],
|
||||
"time": "2016-01-18T06:57:07+00:00"
|
||||
},
|
||||
{
|
||||
"name": "barryvdh/laravel-debugbar",
|
||||
"version": "v2.4.3",
|
||||
@@ -1375,58 +1239,6 @@
|
||||
"description": "A fast and easy to use slugger with full UTF-8 support.",
|
||||
"time": "2015-04-12T19:57:10+00:00"
|
||||
},
|
||||
{
|
||||
"name": "jenssegers/rollbar",
|
||||
"version": "v1.5.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/jenssegers/laravel-rollbar.git",
|
||||
"reference": "d61d6797884df95f6928dee1e23d886ac7086265"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/jenssegers/laravel-rollbar/zipball/d61d6797884df95f6928dee1e23d886ac7086265",
|
||||
"reference": "d61d6797884df95f6928dee1e23d886ac7086265",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"illuminate/support": "^4.0|^5.0",
|
||||
"php": ">=5.4",
|
||||
"rollbar/rollbar": "~0.15"
|
||||
},
|
||||
"require-dev": {
|
||||
"mockery/mockery": "^0.9",
|
||||
"orchestra/testbench": "^3.0",
|
||||
"phpunit/phpunit": "~4.0|~5.0",
|
||||
"satooshi/php-coveralls": "^1.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Jenssegers\\Rollbar\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jens Segers",
|
||||
"homepage": "https://jenssegers.com"
|
||||
}
|
||||
],
|
||||
"description": "Rollbar error monitoring integration for Laravel projects",
|
||||
"homepage": "https://github.com/jenssegers/laravel-rollbar",
|
||||
"keywords": [
|
||||
"error",
|
||||
"laravel",
|
||||
"logging",
|
||||
"monitoring",
|
||||
"rollbar"
|
||||
],
|
||||
"time": "2017-01-25T08:34:12+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laravel/framework",
|
||||
"version": "v5.4.29",
|
||||
@@ -2248,7 +2060,7 @@
|
||||
},
|
||||
{
|
||||
"name": "mtdowling/cron-expression",
|
||||
"version": "v1.2.0",
|
||||
"version": "v1.2.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/mtdowling/cron-expression.git",
|
||||
@@ -2290,61 +2102,6 @@
|
||||
],
|
||||
"time": "2017-01-23T04:29:33+00:00"
|
||||
},
|
||||
{
|
||||
"name": "mtdowling/jmespath.php",
|
||||
"version": "2.4.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/jmespath/jmespath.php.git",
|
||||
"reference": "adcc9531682cf87dfda21e1fd5d0e7a41d292fac"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/jmespath/jmespath.php/zipball/adcc9531682cf87dfda21e1fd5d0e7a41d292fac",
|
||||
"reference": "adcc9531682cf87dfda21e1fd5d0e7a41d292fac",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.4.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "~4.0"
|
||||
},
|
||||
"bin": [
|
||||
"bin/jp.php"
|
||||
],
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.0-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"JmesPath\\": "src/"
|
||||
},
|
||||
"files": [
|
||||
"src/JmesPath.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Michael Dowling",
|
||||
"email": "mtdowling@gmail.com",
|
||||
"homepage": "https://github.com/mtdowling"
|
||||
}
|
||||
],
|
||||
"description": "Declaratively specify how to extract elements from a JSON document",
|
||||
"keywords": [
|
||||
"json",
|
||||
"jsonpath"
|
||||
],
|
||||
"time": "2016-12-03T22:08:25+00:00"
|
||||
},
|
||||
{
|
||||
"name": "neitanod/forceutf8",
|
||||
"version": "v2.0.1",
|
||||
@@ -2434,16 +2191,16 @@
|
||||
},
|
||||
{
|
||||
"name": "nikic/php-parser",
|
||||
"version": "v3.1.1",
|
||||
"version": "v3.1.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/nikic/PHP-Parser.git",
|
||||
"reference": "a1e8e1a30e1352f118feff1a8481066ddc2f234a"
|
||||
"reference": "08131e7ff29de6bb9f12275c7d35df71f25f4d89"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/a1e8e1a30e1352f118feff1a8481066ddc2f234a",
|
||||
"reference": "a1e8e1a30e1352f118feff1a8481066ddc2f234a",
|
||||
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/08131e7ff29de6bb9f12275c7d35df71f25f4d89",
|
||||
"reference": "08131e7ff29de6bb9f12275c7d35df71f25f4d89",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2481,7 +2238,7 @@
|
||||
"parser",
|
||||
"php"
|
||||
],
|
||||
"time": "2017-09-02T17:10:46+00:00"
|
||||
"time": "2017-11-04T11:48:34+00:00"
|
||||
},
|
||||
{
|
||||
"name": "paragonie/random_compat",
|
||||
@@ -3101,16 +2858,16 @@
|
||||
},
|
||||
{
|
||||
"name": "psy/psysh",
|
||||
"version": "v0.8.13",
|
||||
"version": "v0.8.14",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/bobthecow/psysh.git",
|
||||
"reference": "cdb5593c3684bab74e10fcfffe4a0c8d1c39695d"
|
||||
"reference": "91e53c16560bdb8b9592544bb38429ae00d6baee"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/bobthecow/psysh/zipball/cdb5593c3684bab74e10fcfffe4a0c8d1c39695d",
|
||||
"reference": "cdb5593c3684bab74e10fcfffe4a0c8d1c39695d",
|
||||
"url": "https://api.github.com/repos/bobthecow/psysh/zipball/91e53c16560bdb8b9592544bb38429ae00d6baee",
|
||||
"reference": "91e53c16560bdb8b9592544bb38429ae00d6baee",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -3170,7 +2927,7 @@
|
||||
"interactive",
|
||||
"shell"
|
||||
],
|
||||
"time": "2017-10-19T06:13:20+00:00"
|
||||
"time": "2017-11-04T16:06:49+00:00"
|
||||
},
|
||||
{
|
||||
"name": "ramsey/uuid",
|
||||
@@ -3256,31 +3013,40 @@
|
||||
},
|
||||
{
|
||||
"name": "rollbar/rollbar",
|
||||
"version": "v0.18.2",
|
||||
"version": "v1.3.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/rollbar/rollbar-php.git",
|
||||
"reference": "fafe13f8beb669d6bba0137f3703fa808d50cbb7"
|
||||
"reference": "2e092656f49b5bd52eb5ee381b5eece58d82e30e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/rollbar/rollbar-php/zipball/fafe13f8beb669d6bba0137f3703fa808d50cbb7",
|
||||
"reference": "fafe13f8beb669d6bba0137f3703fa808d50cbb7",
|
||||
"url": "https://api.github.com/repos/rollbar/rollbar-php/zipball/2e092656f49b5bd52eb5ee381b5eece58d82e30e",
|
||||
"reference": "2e092656f49b5bd52eb5ee381b5eece58d82e30e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-curl": "*"
|
||||
"ext-curl": "*",
|
||||
"psr/log": "~1.0.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"codeclimate/php-test-reporter": "dev-master",
|
||||
"mockery/mockery": "0.9.*",
|
||||
"phpunit/phpunit": "4.5.*"
|
||||
"monolog/monolog": "*",
|
||||
"packfire/php5.3-compat": "*",
|
||||
"phpmd/phpmd": "@stable",
|
||||
"phpunit/phpunit": "4.8.*",
|
||||
"squizlabs/php_codesniffer": "2.*"
|
||||
},
|
||||
"suggest": {
|
||||
"fluent/logger": "Needed to use the 'fluent' handler for fluentd support",
|
||||
"packfire/php5.3-compat": "for backward compatibility with PHP 5.3"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
"src/Level.php",
|
||||
"src/rollbar.php"
|
||||
]
|
||||
"psr-4": {
|
||||
"Rollbar\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
@@ -3302,7 +3068,75 @@
|
||||
"logging",
|
||||
"monitoring"
|
||||
],
|
||||
"time": "2016-07-05T15:50:29+00:00"
|
||||
"time": "2017-10-27T17:40:44+00:00"
|
||||
},
|
||||
{
|
||||
"name": "rollbar/rollbar-laravel",
|
||||
"version": "v2.2.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/rollbar/rollbar-php-laravel.git",
|
||||
"reference": "8d46138367cc2a45aa9e1097258847cfc6eddbe2"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/rollbar/rollbar-php-laravel/zipball/8d46138367cc2a45aa9e1097258847cfc6eddbe2",
|
||||
"reference": "8d46138367cc2a45aa9e1097258847cfc6eddbe2",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"illuminate/support": "^4.0|^5.0",
|
||||
"php": ">=5.4",
|
||||
"rollbar/rollbar": "^1.3.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"mockery/mockery": "^0.9",
|
||||
"orchestra/testbench": "~3.0",
|
||||
"phpunit/phpunit": "~4.0|~5.0",
|
||||
"satooshi/php-coveralls": "^1.0",
|
||||
"squizlabs/php_codesniffer": "2.*"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Rollbar\\Laravel\\RollbarServiceProvider"
|
||||
],
|
||||
"aliases": {
|
||||
"Rollbar": "Rollbar\\Laravel\\Facades\\Rollbar"
|
||||
}
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Rollbar\\Laravel\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jens Segers",
|
||||
"homepage": "https://jenssegers.com"
|
||||
},
|
||||
{
|
||||
"name": "Artur Moczulski",
|
||||
"email": "artur.moczulski@gmail.com",
|
||||
"role": "Contractor @ Rollbar, Inc."
|
||||
}
|
||||
],
|
||||
"description": "Rollbar error monitoring integration for Laravel projects",
|
||||
"homepage": "https://github.com/rollbar/rollbar-php-laravel",
|
||||
"keywords": [
|
||||
"error",
|
||||
"laravel",
|
||||
"logging",
|
||||
"monitoring",
|
||||
"rollbar"
|
||||
],
|
||||
"time": "2017-09-19T00:20:37+00:00"
|
||||
},
|
||||
{
|
||||
"name": "schuppo/password-strength",
|
||||
@@ -5036,16 +4870,16 @@
|
||||
},
|
||||
{
|
||||
"name": "watson/validating",
|
||||
"version": "3.1.1",
|
||||
"version": "3.1.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/dwightwatson/validating.git",
|
||||
"reference": "ade13078bf2e820e244603446114a28eda51b08c"
|
||||
"reference": "22edd06d45893f5d4f79c9e901bd7fbce174a79f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/dwightwatson/validating/zipball/ade13078bf2e820e244603446114a28eda51b08c",
|
||||
"reference": "ade13078bf2e820e244603446114a28eda51b08c",
|
||||
"url": "https://api.github.com/repos/dwightwatson/validating/zipball/22edd06d45893f5d4f79c9e901bd7fbce174a79f",
|
||||
"reference": "22edd06d45893f5d4f79c9e901bd7fbce174a79f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -5082,7 +4916,7 @@
|
||||
"laravel",
|
||||
"validation"
|
||||
],
|
||||
"time": "2017-10-08T22:42:01+00:00"
|
||||
"time": "2017-11-06T21:35:49+00:00"
|
||||
},
|
||||
{
|
||||
"name": "webmozart/assert",
|
||||
|
||||
+4
-3
@@ -78,7 +78,7 @@ return [
|
||||
|
|
||||
*/
|
||||
|
||||
'locale' => env('APP_LOCALE', 'en_US.UTF-8'),
|
||||
'locale' => env('APP_LOCALE', 'en'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
@@ -121,7 +121,7 @@ return [
|
||||
|
|
||||
*/
|
||||
|
||||
'log' => env('APP_LOG', 'daily'),
|
||||
'log' => env('APP_LOG', 'single'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
@@ -278,7 +278,6 @@ return [
|
||||
*/
|
||||
|
||||
Barryvdh\Debugbar\ServiceProvider::class,
|
||||
Aws\Laravel\AwsServiceProvider::class,
|
||||
Intervention\Image\ImageServiceProvider::class,
|
||||
Collective\Html\HtmlServiceProvider::class,
|
||||
Spatie\Backup\BackupServiceProvider::class,
|
||||
@@ -297,6 +296,8 @@ return [
|
||||
App\Providers\AuthServiceProvider::class,
|
||||
App\Providers\EventServiceProvider::class,
|
||||
App\Providers\RouteServiceProvider::class,
|
||||
App\Providers\SettingsServiceProvider::class,
|
||||
App\Providers\ValidationServiceProvider::class,
|
||||
|
||||
|
||||
/*
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Aws\Laravel\AwsServiceProvider;
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| AWS SDK Configuration
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The configuration options set in this file will be passed directly to the
|
||||
| `Aws\Sdk` object, from which all client objects are created. The minimum
|
||||
| required options are declared here, but the full set of possible options
|
||||
| are documented at:
|
||||
| http://docs.aws.amazon.com/aws-sdk-php/v3/guide/guide/configuration.html
|
||||
|
|
||||
*/
|
||||
|
||||
'region' => env('AWS_REGION', 'us-east-1'),
|
||||
'version' => 'latest',
|
||||
'ua_append' => [
|
||||
'L5MOD/' . AwsServiceProvider::VERSION,
|
||||
],
|
||||
];
|
||||
+7
-3
@@ -61,7 +61,11 @@ return [
|
||||
|
|
||||
*/
|
||||
|
||||
'from' => ['address' => env('MAIL_FROM_ADDR', null), 'name' => env('MAIL_FROM_NAME', null)],
|
||||
'from' =>
|
||||
[
|
||||
'address' => env('MAIL_FROM_ADDR', null),
|
||||
'name' => env('MAIL_FROM_NAME', null)
|
||||
],
|
||||
|
||||
|
||||
/*
|
||||
@@ -76,8 +80,8 @@ return [
|
||||
*/
|
||||
|
||||
'reply_to' => [
|
||||
'address' => env('MAIL_REPLYTO_ADDR', env('MAIL_FROM_ADDR', null)),
|
||||
'name' => env('MAIL_REPLYTO_NAME', env('MAIL_FROM_NAME', null))
|
||||
'address' => env('MAIL_REPLYTO_ADDR',null),
|
||||
'name' => env('MAIL_REPLYTO_NAME', null)
|
||||
],
|
||||
|
||||
/*
|
||||
|
||||
+7
-4
@@ -1,7 +1,10 @@
|
||||
<?php
|
||||
return array (
|
||||
'app_version' => 'v4.1.2',
|
||||
'build_version' => '48',
|
||||
'hash_version' => 'gd21c92f',
|
||||
'full_hash' => 'v4.1.2-48-gd21c92f',
|
||||
'app_version' => 'v4.1.6',
|
||||
'full_app_version' => 'v4.1.6 - build 2963-g83c8449',
|
||||
'build_version' => '2963',
|
||||
'prerelease_version' => '',
|
||||
'hash_version' => 'g83c8449',
|
||||
'full_hash' => 'v4.1.5-76-gb934d2e',
|
||||
'branch' => 'master',
|
||||
);
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use App\Models\Asset;
|
||||
use App\Models\User;
|
||||
use App\Models\Location;
|
||||
|
||||
|
||||
class MigrateDenormedAssetLocations extends Migration
|
||||
{
|
||||
@@ -16,77 +11,11 @@ class MigrateDenormedAssetLocations extends Migration
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
|
||||
// Unassigned
|
||||
$rtd_assets = Asset::whereNull('assigned_to')->with('defaultLoc')->get();
|
||||
\Log::info('Unasigned assets: ');
|
||||
foreach ($rtd_assets as $rtd_asset) {
|
||||
\Log::info('Setting asset '.$rtd_asset->id.' to location: '.$rtd_asset->rtd_location_id." Because asset's default location is: ".$rtd_asset->rtd_location_id);
|
||||
$rtd_asset->location_id=$rtd_asset->rtd_location_id;
|
||||
$rtd_asset->unsetEventDispatcher();
|
||||
$rtd_asset->save();
|
||||
}
|
||||
|
||||
// Assigned to users - ::with('assignedTo') //can't eager-load polymorphic relations?
|
||||
$assigned_user_assets = Asset::where('assigned_type',User::class)->whereNotNull('assigned_to')->get();
|
||||
\Log::debug('User-assigned assets:');
|
||||
foreach ($assigned_user_assets as $assigned_user_asset) {
|
||||
if ($assigned_user_asset->assignedTo->userLoc) {
|
||||
$new_location=$assigned_user_asset->assignedTo->userloc->id;
|
||||
\Log::info(' They are in '.$assigned_user_asset->assignedTo->userloc->name.' which is id: '.$new_location);
|
||||
} else {
|
||||
\Log::info('They have no location! ');
|
||||
$new_location=$assigned_user_asset->rtd_location_id;
|
||||
}
|
||||
$assigned_user_asset->location_id=$new_location;
|
||||
$assigned_user_asset->unsetEventDispatcher();
|
||||
$assigned_user_asset->save();
|
||||
|
||||
}
|
||||
|
||||
// Assigned to locations // with('assetloc')-> //can't eager-load polymorphic relationships
|
||||
$assigned_location_assets = Asset::where('assigned_type',Location::class)->whereNotNull('assigned_to')->get();
|
||||
\Log::info('Location-assigned assets: ');
|
||||
foreach ($assigned_location_assets as $assigned_location_asset) {
|
||||
$assigned_location_asset->location_id=$assigned_location_asset->assignedTo->id;
|
||||
\Log::info('(calculated to be: '.$assigned_location_asset->assetLoc());
|
||||
$assigned_location_asset->unsetEventDispatcher();
|
||||
$assigned_location_asset->save();
|
||||
}
|
||||
|
||||
// Assigned to assets
|
||||
$assigned_asset_assets = Asset::where('assigned_type',Asset::class)->whereNotNull('assigned_to')->with('assetloc')->get();
|
||||
\Log::info('Asset-assigned assets: ');
|
||||
foreach ($assigned_asset_assets as $assigned_asset_asset) {
|
||||
\Log::info('This asset is: '.$assigned_asset_asset->assignedTo->asset_tag);
|
||||
if (($assigned_asset_asset->assignedTo) && ($assigned_asset_asset->assignedTo->location)) {
|
||||
\Log::info('They are in '.$assigned_asset_asset->assignedTo->location->name);
|
||||
}
|
||||
if ($assigned_asset_asset->assetloc) {
|
||||
\Log::info('User location is: '.$assigned_asset_asset->assetloc->name);
|
||||
\Log::info('Setting asset '.$assigned_asset_asset->id.' location to '.$assigned_asset_asset->assetloc->id.' ('.$assigned_asset_asset->assetloc->name.')');
|
||||
$assigned_asset_asset->location_id=$assigned_asset_asset->assetloc->id;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
$unassigned_assets=Asset::whereNull("location_id")->get();
|
||||
foreach($unassigned_assets as $unassigned_asset) {
|
||||
\Log::info('Asset: '.$unassigned_asset->id.' still has no location');
|
||||
}
|
||||
|
||||
$assets = Asset::get();
|
||||
|
||||
foreach ($assets as $asset) {
|
||||
if (($asset) && ($asset->assetLoc()) && ($asset->location_id != $asset->assetLoc()->id)) {
|
||||
\Log::info('MISMATCH MISMATCH '.$asset->id. "doesn't match its location");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// the contents of this migration have moved to the `php artisan snipeit:sync-asset-locations` script
|
||||
// I know its gross to edit a migration, but we had to do this for support purposes. - @snipe
|
||||
Artisan::call('snipeit:sync-asset-locations', ['--output' => 'all']);
|
||||
$output = Artisan::output();
|
||||
\Log::info($output);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class AddAlertMenuSetting extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('settings', function (Blueprint $table) {
|
||||
$table->boolean('show_alerts_in_menu')->default(1);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('settings', function (Blueprint $table) {
|
||||
$table->dropColumn('show_alerts_in_menu');
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class LabelsDisplayCompanyName extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('settings', function (Blueprint $table) {
|
||||
$table->boolean('labels_display_company_name')->default(0);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('settings', function ($table) {
|
||||
$table->dropColumn(
|
||||
'labels_display_company_name'
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
use Illuminate\Database\Seeder;
|
||||
use App\Models\CustomField;
|
||||
use App\Models\CustomFieldset;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
|
||||
@@ -21,6 +22,8 @@ class CustomFieldSeeder extends Seeder
|
||||
}
|
||||
}
|
||||
CustomField::truncate();
|
||||
CustomFieldset::truncate();
|
||||
DB::table('custom_field_custom_fieldset')->truncate();
|
||||
factory(CustomField::class, 4)->create();
|
||||
|
||||
}
|
||||
|
||||
@@ -33,6 +33,10 @@ class DatabaseSeeder extends Seeder
|
||||
$this->call(ActionlogSeeder::class);
|
||||
$this->call(CustomFieldSeeder::class);
|
||||
|
||||
Artisan::call('snipeit:sync-asset-locations', ['--output' => 'all']);
|
||||
$output = Artisan::output();
|
||||
\Log::info($output);
|
||||
|
||||
Model::reguard();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,8 @@ MAIL_PASSWORD=${MAIL_ENV_PASSWORD}
|
||||
MAIL_ENCRYPTION=${MAIL_ENV_ENCRYPTION}
|
||||
MAIL_FROM_ADDR=${MAIL_ENV_FROM_ADDR}
|
||||
MAIL_FROM_NAME=${MAIL_ENV_FROM_NAME}
|
||||
MAIL_REPLYTO_ADDR=${MAIL_ENV_FROM_ADDR}
|
||||
MAIL_REPLYTO_NAME=${MAIL_ENV_FROM_NAME}
|
||||
|
||||
|
||||
# --------------------------------------------
|
||||
|
||||
+1
-1
@@ -26,8 +26,8 @@
|
||||
"bootstrap-datepicker": "^1.6.4",
|
||||
"bootstrap-less": "^3.3.8",
|
||||
"ekko-lightbox": "^5.1.1",
|
||||
"fastclick": "^1.0.6",
|
||||
"font-awesome": "^4.7.0",
|
||||
"icheck": "^1.0.2",
|
||||
"jquery-slimscroll": "^1.3.8",
|
||||
"jquery-ui": "^1.12.1",
|
||||
"jquery-ui-bundle": "^1.12.1",
|
||||
|
||||
+17
-17
File diff suppressed because one or more lines are too long
Vendored
+17
-17
File diff suppressed because one or more lines are too long
@@ -8,7 +8,7 @@
|
||||
"/css/app.css.map": "/css/app.css.map?id=bdbe05e6ecd70ccfac72",
|
||||
"/css/overrides.css.map": "/css/overrides.css.map?id=898c91d4a425b01b589b",
|
||||
"/css/dist/all.css": "/css/dist/all.css?id=7c3842d2639193ac7e88",
|
||||
"/js/dist/all.js": "/js/dist/all.js?id=45f8944e6ec45cec9861",
|
||||
"/js/dist/all.js": "/js/dist/all.js?id=7b52ead3a55086ea1f8d",
|
||||
"/css/build/all.css": "/css/build/all.css?id=7c3842d2639193ac7e88",
|
||||
"/js/build/all.js": "/js/build/all.js?id=45f8944e6ec45cec9861"
|
||||
"/js/build/all.js": "/js/build/all.js?id=7b52ead3a55086ea1f8d"
|
||||
}
|
||||
@@ -19,5 +19,9 @@
|
||||
</rule>
|
||||
</rules>
|
||||
</rewrite>
|
||||
<staticContent>
|
||||
<remove fileExtension=".woff2" />
|
||||
<mimeMap fileExtension=".woff2" mimeType="application/x-font-woff2" />
|
||||
</staticContent>
|
||||
</system.webServer>
|
||||
</configuration>
|
||||
|
||||
@@ -63,7 +63,7 @@ $.AdminLTE.options = {
|
||||
//native touch experience with touch devices. If you
|
||||
//choose to enable the plugin, make sure you load the script
|
||||
//before AdminLTE's app.js
|
||||
enableFastclick: true,
|
||||
enableFastclick: false,
|
||||
//Control Sidebar Options
|
||||
enableControlSidebar: true,
|
||||
controlSidebarOptions: {
|
||||
|
||||
@@ -194,7 +194,9 @@ $(document).ready(function () {
|
||||
link.select2({
|
||||
|
||||
ajax: {
|
||||
url: baseUrl + '/api/v1/' + endpoint + '/selectlist',
|
||||
|
||||
// the baseUrl includes a trailing slash
|
||||
url: baseUrl + 'api/v1/' + endpoint + '/selectlist',
|
||||
dataType: 'json',
|
||||
delay: 250,
|
||||
headers: {
|
||||
@@ -253,8 +255,40 @@ $(document).ready(function () {
|
||||
return datalist.text;
|
||||
}
|
||||
|
||||
// This handles the radio button selectors for the checkout-to-foo options
|
||||
// on asset checkout and also on asset edit
|
||||
$(function() {
|
||||
$('input[name=checkout_to_type]').on("change",function () {
|
||||
var assignto_type = $('input[name=checkout_to_type]:checked').val();
|
||||
var userid = $('#assigned_user option:selected').val();
|
||||
|
||||
if (assignto_type == 'asset') {
|
||||
$('#current_assets_box').fadeOut();
|
||||
$('#assigned_asset').show();
|
||||
$('#assigned_user').hide();
|
||||
$('#assigned_location').hide();
|
||||
$('.notification-callout').fadeOut();
|
||||
|
||||
} else if (assignto_type == 'location') {
|
||||
$('#current_assets_box').fadeOut();
|
||||
$('#assigned_asset').hide();
|
||||
$('#assigned_user').hide();
|
||||
$('#assigned_location').show();
|
||||
$('.notification-callout').fadeOut();
|
||||
} else {
|
||||
|
||||
$('#assigned_asset').hide();
|
||||
$('#assigned_user').show();
|
||||
$('#assigned_location').hide();
|
||||
if (userid) {
|
||||
$('#current_assets_box').fadeIn();
|
||||
}
|
||||
$('.notification-callout').fadeIn();
|
||||
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
});
|
||||
|
||||
@@ -20,6 +20,7 @@ return array(
|
||||
'field_element_short' => 'element',
|
||||
'field_format' => 'formaat',
|
||||
'field_custom_format' => 'Gepasmaakte formaat',
|
||||
'field_custom_format_help' => 'This field allows you to use a regex expression for validation. It should start with "regex:" - for example, to validate that a custom field value contains a valid IMEI (15 numeric digits), you would use <code>regex:/^[0-9]{15}$/</code>.',
|
||||
'required' => 'vereis',
|
||||
'req' => 'Req.',
|
||||
'used_by_models' => 'Gebruik deur modelle',
|
||||
|
||||
@@ -61,7 +61,8 @@ return array(
|
||||
'error' => 'Bate is nie nagegaan nie, probeer asseblief weer',
|
||||
'success' => 'Die bate is suksesvol nagegaan.',
|
||||
'user_does_not_exist' => 'Die gebruiker is ongeldig. Probeer asseblief weer.',
|
||||
'not_available' => 'Die bate is nie beskikbaar vir die kassa nie!'
|
||||
'not_available' => 'Die bate is nie beskikbaar vir die kassa nie!',
|
||||
'no_assets_selected' => 'You must select at least one asset from the list'
|
||||
),
|
||||
|
||||
'checkin' => array(
|
||||
|
||||
@@ -23,6 +23,8 @@ return array(
|
||||
'confirm_purge_help' => 'Tik die teks "DELETE" in die onderstaande blokkie om jou geskrapde rekords te verwyder. Hierdie handeling kan nie ongedaan gemaak word nie.',
|
||||
'custom_css' => 'Aangepaste CSS',
|
||||
'custom_css_help' => 'Voer enige aangepaste CSS-oortredings in wat u graag wil gebruik. Moenie die <style></style>-etikette insluit nie.',
|
||||
'custom_forgot_pass_url' => 'Custom Password Reset URL',
|
||||
'custom_forgot_pass_url_help' => 'This replaces the built-in forgotten password URL on the login screen, useful to direct people to internal or hosted LDAP password reset functionality. It will effectively disable local user forgotten password functionality.',
|
||||
'default_currency' => 'Verstek Geld',
|
||||
'default_eula_text' => 'Standaard EULA',
|
||||
'default_language' => 'Verstek taal',
|
||||
@@ -44,6 +46,8 @@ return array(
|
||||
'ldap_enabled' => 'LDAP aangeskakel',
|
||||
'ldap_integration' => 'LDAP-integrasie',
|
||||
'ldap_settings' => 'LDAP-instellings',
|
||||
'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_server' => 'LDAP-bediener',
|
||||
'ldap_server_help' => 'Dit moet begin met ldap: // (vir unencrypted of TLS) of ldaps: // (vir SSL)',
|
||||
'ldap_server_cert' => 'LDAP SSL-sertifikaat-validering',
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
return array(
|
||||
|
||||
'does_not_exist' => 'Verskaffer bestaan nie.',
|
||||
'assoc_users' => 'Hierdie verskaffer is tans geassosieer met ten minste een model en kan nie uitgevee word nie. Dateer asseblief jou modelle op om nie langer hierdie verskaffer te verwys nie en probeer weer.',
|
||||
|
||||
|
||||
'create' => array(
|
||||
'error' => 'Verskaffer is nie geskep nie, probeer asseblief weer.',
|
||||
@@ -18,7 +18,10 @@ return array(
|
||||
'delete' => array(
|
||||
'confirm' => 'Is jy seker jy wil hierdie verskaffer uitvee?',
|
||||
'error' => 'Daar was \'n probleem met die verwydering van die verskaffer. Probeer asseblief weer.',
|
||||
'success' => 'Verskaffer is suksesvol verwyder.'
|
||||
'success' => 'Verskaffer is suksesvol verwyder.',
|
||||
'assoc_assets' => 'This supplier is currently associated with :asset_count asset(s) and cannot be deleted. Please update your assets to no longer reference this supplier and try again. ',
|
||||
'assoc_licenses' => 'This supplier is currently associated with :licenses_count licences(s) and cannot be deleted. Please update your licenses to no longer reference this supplier and try again. ',
|
||||
'assoc_maintenances' => 'This supplier is currently associated with :asset_maintenances_count asset maintenances(s) and cannot be deleted. Please update your asset maintenances to no longer reference this supplier and try again. ',
|
||||
)
|
||||
|
||||
);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user