mirror of
https://github.com/snipe/snipe-it.git
synced 2025-02-02 08:21:09 -08:00
Merge branch 'develop' into fixes/bulk-checkin-logging
# Conflicts: # app/Http/Controllers/Users/BulkUsersController.php
This commit is contained in:
commit
f2b78d18a4
|
@ -3172,6 +3172,15 @@
|
|||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "arne-kroeger",
|
||||
"name": "arne-kroeger",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/65785975?v=4",
|
||||
"profile": "https://github.com/arne-kroeger",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ Thanks goes to all of these wonderful people ([emoji key](https://github.com/ken
|
|||
| [<img src="https://avatars.githubusercontent.com/u/111287779?v=4" width="110px;"/><br /><sub>NojoudAlshehri</sub>](https://github.com/NojoudAlshehri)<br />[💻](https://github.com/snipe/snipe-it/commits?author=NojoudAlshehri "Code") | [<img src="https://avatars.githubusercontent.com/u/54367449?v=4" width="110px;"/><br /><sub>Stefan Stidl</sub>](https://github.com/stefanstidlffg)<br />[💻](https://github.com/snipe/snipe-it/commits?author=stefanstidlffg "Code") | [<img src="https://avatars.githubusercontent.com/u/87803479?v=4" width="110px;"/><br /><sub>Quentin Aymard</sub>](https://github.com/qay21)<br />[💻](https://github.com/snipe/snipe-it/commits?author=qay21 "Code") | [<img src="https://avatars.githubusercontent.com/u/5396871?v=4" width="110px;"/><br /><sub>Grant Le Roux</sub>](https://github.com/cram42)<br />[💻](https://github.com/snipe/snipe-it/commits?author=cram42 "Code") | [<img src="https://avatars.githubusercontent.com/u/58479551?v=4" width="110px;"/><br /><sub>Bogdan</sub>](http://@singrity)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Singrity "Code") | [<img src="https://avatars.githubusercontent.com/u/3483684?v=4" width="110px;"/><br /><sub>mmanjos</sub>](https://github.com/mmanjos)<br />[💻](https://github.com/snipe/snipe-it/commits?author=mmanjos "Code") | [<img src="https://avatars.githubusercontent.com/u/7429229?v=4" width="110px;"/><br /><sub>Abdelaziz Faki</sub>](https://azooz2014.github.io/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Azooz2014 "Code") |
|
||||
| [<img src="https://avatars.githubusercontent.com/u/47315739?v=4" width="110px;"/><br /><sub>bilias</sub>](https://github.com/bilias)<br />[💻](https://github.com/snipe/snipe-it/commits?author=bilias "Code") | [<img src="https://avatars.githubusercontent.com/u/2565989?v=4" width="110px;"/><br /><sub>coach1988</sub>](https://github.com/coach1988)<br />[💻](https://github.com/snipe/snipe-it/commits?author=coach1988 "Code") | [<img src="https://avatars.githubusercontent.com/u/11910225?v=4" width="110px;"/><br /><sub>MrM</sub>](https://github.com/mauro-miatello)<br />[💻](https://github.com/snipe/snipe-it/commits?author=mauro-miatello "Code") | [<img src="https://avatars.githubusercontent.com/u/60405354?v=4" width="110px;"/><br /><sub>koiakoia</sub>](https://github.com/koiakoia)<br />[💻](https://github.com/snipe/snipe-it/commits?author=koiakoia "Code") | [<img src="https://avatars.githubusercontent.com/u/5323832?v=4" width="110px;"/><br /><sub>Mustafa Online</sub>](https://github.com/mustafa-online)<br />[💻](https://github.com/snipe/snipe-it/commits?author=mustafa-online "Code") | [<img src="https://avatars.githubusercontent.com/u/104601439?v=4" width="110px;"/><br /><sub>franceslui</sub>](https://github.com/franceslui)<br />[💻](https://github.com/snipe/snipe-it/commits?author=franceslui "Code") | [<img src="https://avatars.githubusercontent.com/u/125313163?v=4" width="110px;"/><br /><sub>Q4kK</sub>](https://github.com/Q4kK)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Q4kK "Code") |
|
||||
| [<img src="https://avatars.githubusercontent.com/u/55590532?v=4" width="110px;"/><br /><sub>squintfox</sub>](https://github.com/squintfox)<br />[💻](https://github.com/snipe/snipe-it/commits?author=squintfox "Code") | [<img src="https://avatars.githubusercontent.com/u/1380084?v=4" width="110px;"/><br /><sub>Jeff Clay</sub>](https://github.com/jeffclay)<br />[💻](https://github.com/snipe/snipe-it/commits?author=jeffclay "Code") | [<img src="https://avatars.githubusercontent.com/u/52716446?v=4" width="110px;"/><br /><sub>Phil J R</sub>](https://github.com/PP-JN-RL)<br />[💻](https://github.com/snipe/snipe-it/commits?author=PP-JN-RL "Code") | [<img src="https://avatars.githubusercontent.com/u/1496725?v=4" width="110px;"/><br /><sub>i_virus</sub>](https://www.corelight.com/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=chandanchowdhury "Code") | [<img src="https://avatars.githubusercontent.com/u/1020541?v=4" width="110px;"/><br /><sub>Paul Grime</sub>](https://github.com/gitgrimbo)<br />[💻](https://github.com/snipe/snipe-it/commits?author=gitgrimbo "Code") | [<img src="https://avatars.githubusercontent.com/u/922815?v=4" width="110px;"/><br /><sub>Lee Porte</sub>](https://leeporte.co.uk)<br />[💻](https://github.com/snipe/snipe-it/commits?author=LeePorte "Code") | [<img src="https://avatars.githubusercontent.com/u/23613427?v=4" width="110px;"/><br /><sub>BRYAN </sub>](https://github.com/bryanlopezinc)<br />[💻](https://github.com/snipe/snipe-it/commits?author=bryanlopezinc "Code") [⚠️](https://github.com/snipe/snipe-it/commits?author=bryanlopezinc "Tests") |
|
||||
| [<img src="https://avatars.githubusercontent.com/u/64061710?v=4" width="110px;"/><br /><sub>U-H-T</sub>](https://github.com/U-H-T)<br />[💻](https://github.com/snipe/snipe-it/commits?author=U-H-T "Code") | [<img src="https://avatars.githubusercontent.com/u/5395363?v=4" width="110px;"/><br /><sub>Matt Tyree</sub>](https://github.com/Tyree)<br />[📖](https://github.com/snipe/snipe-it/commits?author=Tyree "Documentation") | [<img src="https://avatars.githubusercontent.com/u/292081?v=4" width="110px;"/><br /><sub>Florent Bervas</sub>](http://spoontux.net)<br />[💻](https://github.com/snipe/snipe-it/commits?author=FlorentDotMe "Code") | [<img src="https://avatars.githubusercontent.com/u/4498077?v=4" width="110px;"/><br /><sub>Daniel Albertsen</sub>](https://ditscheri.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=dbakan "Code") | [<img src="https://avatars.githubusercontent.com/u/100710244?v=4" width="110px;"/><br /><sub>r-xyz</sub>](https://github.com/r-xyz)<br />[💻](https://github.com/snipe/snipe-it/commits?author=r-xyz "Code") | [<img src="https://avatars.githubusercontent.com/u/47491036?v=4" width="110px;"/><br /><sub>Steven Mainor</sub>](https://github.com/DrekiDegga)<br />[💻](https://github.com/snipe/snipe-it/commits?author=DrekiDegga "Code") |
|
||||
| [<img src="https://avatars.githubusercontent.com/u/64061710?v=4" width="110px;"/><br /><sub>U-H-T</sub>](https://github.com/U-H-T)<br />[💻](https://github.com/snipe/snipe-it/commits?author=U-H-T "Code") | [<img src="https://avatars.githubusercontent.com/u/5395363?v=4" width="110px;"/><br /><sub>Matt Tyree</sub>](https://github.com/Tyree)<br />[📖](https://github.com/snipe/snipe-it/commits?author=Tyree "Documentation") | [<img src="https://avatars.githubusercontent.com/u/292081?v=4" width="110px;"/><br /><sub>Florent Bervas</sub>](http://spoontux.net)<br />[💻](https://github.com/snipe/snipe-it/commits?author=FlorentDotMe "Code") | [<img src="https://avatars.githubusercontent.com/u/4498077?v=4" width="110px;"/><br /><sub>Daniel Albertsen</sub>](https://ditscheri.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=dbakan "Code") | [<img src="https://avatars.githubusercontent.com/u/100710244?v=4" width="110px;"/><br /><sub>r-xyz</sub>](https://github.com/r-xyz)<br />[💻](https://github.com/snipe/snipe-it/commits?author=r-xyz "Code") | [<img src="https://avatars.githubusercontent.com/u/47491036?v=4" width="110px;"/><br /><sub>Steven Mainor</sub>](https://github.com/DrekiDegga)<br />[💻](https://github.com/snipe/snipe-it/commits?author=DrekiDegga "Code") | [<img src="https://avatars.githubusercontent.com/u/65785975?v=4" width="110px;"/><br /><sub>arne-kroeger</sub>](https://github.com/arne-kroeger)<br />[💻](https://github.com/snipe/snipe-it/commits?author=arne-kroeger "Code") |
|
||||
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
||||
|
||||
This project follows the [all-contributors](https://github.com/kentcdodds/all-contributors) specification. Contributions of any kind welcome!
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\Accessory;
|
||||
use App\Models\Actionlog;
|
||||
use App\Models\Asset;
|
||||
use App\Models\AssetModel;
|
||||
use App\Models\Category;
|
||||
|
@ -15,6 +16,8 @@ use App\Models\Statuslabel;
|
|||
use App\Models\Supplier;
|
||||
use App\Models\User;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class Purge extends Command
|
||||
{
|
||||
|
@ -141,6 +144,20 @@ class Purge extends Command
|
|||
$this->info($users->count().' users purged.');
|
||||
$user_assoc = 0;
|
||||
foreach ($users as $user) {
|
||||
|
||||
$rel_path = 'private_uploads/users';
|
||||
$filenames = Actionlog::where('action_type', 'uploaded')
|
||||
->where('item_id', $user->id)
|
||||
->pluck('filename');
|
||||
foreach($filenames as $filename) {
|
||||
try {
|
||||
if (Storage::exists($rel_path . '/' . $filename)) {
|
||||
Storage::delete($rel_path . '/' . $filename);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
Log::info('An error occurred while deleting files: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
$this->info('- User "'.$user->username.'" deleted.');
|
||||
$user_assoc += $user->userlog()->count();
|
||||
$user->userlog()->forceDelete();
|
||||
|
|
|
@ -30,8 +30,11 @@ class SQLStreamer {
|
|||
public function parse_sql(string $line): string {
|
||||
// take into account the 'start of line or not' setting as an instance variable?
|
||||
// 'continuation' lines for a permitted statement are PERMITTED.
|
||||
// remove *only* line-feeds & carriage-returns; helpful for regexes against lines from
|
||||
// Windows dumps
|
||||
$line = trim($line, "\r\n");
|
||||
if($this->statement_is_permitted && $line[0] === ' ') {
|
||||
return $line;
|
||||
return $line . "\n"; //re-add the newline
|
||||
}
|
||||
|
||||
$table_regex = '`?([a-zA-Z0-9_]+)`?';
|
||||
|
@ -42,8 +45,12 @@ class SQLStreamer {
|
|||
"/^(INSERT INTO )$table_regex(.*)$/" => false,
|
||||
"/^UNLOCK TABLES/" => false,
|
||||
// "/^\\) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;/" => false, // FIXME not sure what to do here?
|
||||
"/^\\)[a-zA-Z0-9_= ]*;$/" => false
|
||||
// ^^^^^^ that bit should *exit* the 'perimitted' black
|
||||
"/^\\)[a-zA-Z0-9_= ]*;$/" => false,
|
||||
// ^^^^^^ that bit should *exit* the 'permitted' block
|
||||
"/^\\(.*\\)[,;]$/" => false, //older MySQL dump style with one set of values per line
|
||||
/* we *could* have made the ^INSERT INTO blah VALUES$ turn on the capturing state, and closed it with
|
||||
a ^(blahblah);$ but it's cleaner to not have to manage the state machine. We're just going to
|
||||
assume that (blahblah), or (blahblah); are values for INSERT and are always acceptable. */
|
||||
];
|
||||
|
||||
foreach($allowed_statements as $statement => $statechange) {
|
||||
|
@ -67,7 +74,7 @@ class SQLStreamer {
|
|||
}
|
||||
//how do we *replace* the tablename?
|
||||
// print "RETURNING LINE: $line";
|
||||
return $line;
|
||||
return $line . "\n"; //re-add newline
|
||||
}
|
||||
}
|
||||
// all that is not allowed is denied.
|
||||
|
@ -85,7 +92,7 @@ class SQLStreamer {
|
|||
$parser->line_aware_piping(); // <----- THIS is doing the heavy lifting!
|
||||
|
||||
$check_tables = ['settings' => null, 'migrations' => null /* 'assets' => null */]; //TODO - move to statics?
|
||||
//can't use 'users' because the 'accessories_users' table?
|
||||
//can't use 'users' because the 'accessories_checkout' table?
|
||||
// can't use 'assets' because 'ver1_components_assets'
|
||||
foreach($check_tables as $check_table => $_ignore) {
|
||||
foreach ($parser->tablenames as $tablename => $_count) {
|
||||
|
@ -164,7 +171,8 @@ class RestoreFromBackup extends Command
|
|||
{filename : The zip file to be migrated}
|
||||
{--no-progress : Don\'t show a progress bar}
|
||||
{--sanitize-guess-prefix : Guess and output the table-prefix needed to "sanitize" the SQL}
|
||||
{--sanitize-with-prefix= : "Sanitize" the SQL, using the passed-in table prefix (can be learned from --sanitize-guess-prefix). Pass as just \'--sanitize-with-prefix=\' to use no prefix}';
|
||||
{--sanitize-with-prefix= : "Sanitize" the SQL, using the passed-in table prefix (can be learned from --sanitize-guess-prefix). Pass as just \'--sanitize-with-prefix=\' to use no prefix}
|
||||
{--sql-stdout-only : ONLY "Sanitize" the SQL and print it to stdout - useful for debugging - probably requires --sanitize-with-prefix= }';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
|
@ -365,6 +373,15 @@ class RestoreFromBackup extends Command
|
|||
return $this->info("Re-run this command with '--sanitize-with-prefix=".$prefix."' to see an attempt to sanitze your SQL.");
|
||||
}
|
||||
|
||||
// If we're doing --sql-stdout-only, handle that now so we don't have to open pipes to mysql and all of that silliness
|
||||
if ($this->option('sql-stdout-only')) {
|
||||
$sql_importer = new SQLStreamer($sql_contents, STDOUT, $this->option('sanitize-with-prefix'));
|
||||
$bytes_read = $sql_importer->line_aware_piping();
|
||||
return $this->warn("$bytes_read total bytes read");
|
||||
//TODO - it'd be nice to dump this message to STDERR so that STDOUT is just pure SQL,
|
||||
// which would be good for redirecting to a file, and not having to trim the last line off of it
|
||||
}
|
||||
|
||||
//how to invoke the restore?
|
||||
$pipes = [];
|
||||
|
||||
|
@ -466,6 +483,9 @@ class RestoreFromBackup extends Command
|
|||
$ugly_file_name = $za->statIndex($file_details['index'])['name'];
|
||||
$fp = $za->getStream($ugly_file_name);
|
||||
//$this->info("Weird problem, here are file details? ".print_r($file_details,true));
|
||||
if (!is_dir($file_details['dest'])) {
|
||||
mkdir($file_details['dest'], 0755, true); //0755 is what Laravel uses, so we do that
|
||||
}
|
||||
$migrated_file = fopen($file_details['dest'].'/'.basename($pretty_file_name), 'w');
|
||||
while (($buffer = fgets($fp, SQLStreamer::$buffer_size)) !== false) {
|
||||
fwrite($migrated_file, $buffer);
|
||||
|
|
|
@ -721,7 +721,7 @@ class Helper
|
|||
{
|
||||
$alert_threshold = \App\Models\Setting::getSettings()->alert_threshold;
|
||||
$consumables = Consumable::withCount('consumableAssignments as consumable_assignments_count')->whereNotNull('min_amt')->get();
|
||||
$accessories = Accessory::withCount('users as users_count')->whereNotNull('min_amt')->get();
|
||||
$accessories = Accessory::withCount('checkouts as checkouts_count')->whereNotNull('min_amt')->get();
|
||||
$components = Component::whereNotNull('min_amt')->get();
|
||||
$asset_models = AssetModel::where('min_amt', '>', 0)->get();
|
||||
$licenses = License::where('min_amt', '>', 0)->get();
|
||||
|
@ -749,7 +749,7 @@ class Helper
|
|||
}
|
||||
|
||||
foreach ($accessories as $accessory) {
|
||||
$avail = $accessory->qty - $accessory->users_count;
|
||||
$avail = $accessory->qty - $accessory->checkouts_count;
|
||||
if ($avail < ($accessory->min_amt) + $alert_threshold) {
|
||||
if ($accessory->qty > 0) {
|
||||
$percent = number_format((($avail / $accessory->qty) * 100), 0);
|
||||
|
@ -1484,35 +1484,57 @@ class Helper
|
|||
}
|
||||
|
||||
|
||||
static public function getRedirectOption($request, $id, $table, $asset_id = null)
|
||||
static public function getRedirectOption($request, $id, $table, $item_id = null)
|
||||
{
|
||||
|
||||
$redirect_option = Session::get('redirect_option');
|
||||
$checkout_to_type = Session::get('checkout_to_type');
|
||||
|
||||
//return to index
|
||||
if ($redirect_option == '0') {
|
||||
// return to index
|
||||
if ($redirect_option == 'index') {
|
||||
switch ($table) {
|
||||
case "Assets":
|
||||
return redirect()->route('hardware.index')->with('success', trans('admin/hardware/message.checkout.success'));
|
||||
return route('hardware.index');
|
||||
case "Users":
|
||||
return route('users.index');
|
||||
case "Licenses":
|
||||
return route('licenses.index');
|
||||
case "Accessories":
|
||||
return route('accessories.index');
|
||||
case "Components":
|
||||
return route('components.index');
|
||||
case "Consumables":
|
||||
return route('consumables.index');
|
||||
}
|
||||
}
|
||||
//return to thing being assigned
|
||||
if ($redirect_option == '1') {
|
||||
|
||||
// return to thing being assigned
|
||||
if ($redirect_option == 'item') {
|
||||
switch ($table) {
|
||||
case "Assets":
|
||||
return redirect()->route('hardware.show', $id ? $id : $asset_id)->with('success', trans('admin/hardware/message.checkout.success'));
|
||||
return route('hardware.show', $id ?? $item_id);
|
||||
case "Users":
|
||||
return route('users.show', $id ?? $item_id);
|
||||
case "Licenses":
|
||||
return route('licenses.show', $id ?? $item_id);
|
||||
case "Accessories":
|
||||
return route('accessories.show', $id ?? $item_id);
|
||||
case "Components":
|
||||
return route('components.show', $id ?? $item_id);
|
||||
case "Consumables":
|
||||
return route('consumables.show', $id ?? $item_id);
|
||||
}
|
||||
}
|
||||
//return to thing being assigned to
|
||||
if ($redirect_option == '2') {
|
||||
|
||||
// return to assignment target
|
||||
if ($redirect_option == 'target') {
|
||||
switch ($checkout_to_type) {
|
||||
case 'user':
|
||||
return redirect()->route('users.show', $request->assigned_user)->with('success', trans('admin/hardware/message.checkout.success'));
|
||||
return route('users.show', ['user' => $request->assigned_user]);
|
||||
case 'location':
|
||||
return redirect()->route('locations.show', $request->assigned_location)->with('success', trans('admin/hardware/message.checkout.success'));
|
||||
return route('locations.show', ['location' => $request->assigned_location]);
|
||||
case 'asset':
|
||||
return redirect()->route('hardware.show', $request->assigned_asset)->with('success', trans('admin/hardware/message.checkout.success'));
|
||||
return route('hardware.show', ['hardware' => $request->assigned_asset]);
|
||||
}
|
||||
}
|
||||
return redirect()->back()->with('error', trans('admin/hardware/message.checkout.error'));
|
||||
|
|
|
@ -79,10 +79,11 @@ class AccessoriesController extends Controller
|
|||
|
||||
$accessory = $request->handleImages($accessory);
|
||||
|
||||
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
||||
// Was the accessory created?
|
||||
if ($accessory->save()) {
|
||||
// Redirect to the new accessory page
|
||||
return redirect()->route('accessories.index')->with('success', trans('admin/accessories/message.create.success'));
|
||||
return redirect()->to(Helper::getRedirectOption($request, $accessory->id, 'Accessories'))->with('success', trans('admin/accessories/message.create.success'));
|
||||
}
|
||||
|
||||
return redirect()->back()->withInput()->withErrors($accessory->getErrors());
|
||||
|
@ -143,12 +144,12 @@ class AccessoriesController extends Controller
|
|||
*/
|
||||
public function update(ImageUploadRequest $request, $accessoryId = null) : RedirectResponse
|
||||
{
|
||||
if ($accessory = Accessory::withCount('users as users_count')->find($accessoryId)) {
|
||||
if ($accessory = Accessory::withCount('checkouts as checkouts_count')->find($accessoryId)) {
|
||||
|
||||
$this->authorize($accessory);
|
||||
|
||||
$validator = Validator::make($request->all(), [
|
||||
"qty" => "required|numeric|min:$accessory->users_count"
|
||||
"qty" => "required|numeric|min:$accessory->checkouts_count"
|
||||
]);
|
||||
|
||||
if ($validator->fails()) {
|
||||
|
@ -176,9 +177,10 @@ class AccessoriesController extends Controller
|
|||
|
||||
$accessory = $request->handleImages($accessory);
|
||||
|
||||
// Was the accessory updated?
|
||||
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
||||
|
||||
if ($accessory->save()) {
|
||||
return redirect()->route('accessories.index')->with('success', trans('admin/accessories/message.update.success'));
|
||||
return redirect()->to(Helper::getRedirectOption($request, $accessory->id, 'Accessories'))->with('success', trans('admin/accessories/message.update.success'));
|
||||
}
|
||||
} else {
|
||||
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.does_not_exist'));
|
||||
|
@ -231,7 +233,7 @@ class AccessoriesController extends Controller
|
|||
*/
|
||||
public function show($accessoryID = null) : View | RedirectResponse
|
||||
{
|
||||
$accessory = Accessory::withCount('users as users_count')->find($accessoryID);
|
||||
$accessory = Accessory::withCount('checkouts as checkouts_count')->find($accessoryID);
|
||||
$this->authorize('view', $accessory);
|
||||
if (isset($accessory->id)) {
|
||||
return view('accessories/view', compact('accessory'));
|
||||
|
|
|
@ -3,8 +3,10 @@
|
|||
namespace App\Http\Controllers\Accessories;
|
||||
|
||||
use App\Events\CheckoutableCheckedIn;
|
||||
use App\Helpers\Helper;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Accessory;
|
||||
use App\Models\AccessoryCheckout;
|
||||
use App\Models\User;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
@ -23,7 +25,7 @@ class AccessoryCheckinController extends Controller
|
|||
*/
|
||||
public function create($accessoryUserId = null, $backto = null) : View | RedirectResponse
|
||||
{
|
||||
if (is_null($accessory_user = DB::table('accessories_users')->find($accessoryUserId))) {
|
||||
if (is_null($accessory_user = DB::table('accessories_checkout')->find($accessoryUserId))) {
|
||||
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.not_found'));
|
||||
}
|
||||
|
||||
|
@ -38,16 +40,16 @@ class AccessoryCheckinController extends Controller
|
|||
*
|
||||
* @uses Accessory::checkin_email() to determine if an email can and should be sent
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param null $accessoryUserId
|
||||
* @param null $accessoryCheckoutId
|
||||
* @param string $backto
|
||||
*/
|
||||
public function store(Request $request, $accessoryUserId = null, $backto = null) : RedirectResponse
|
||||
public function store(Request $request, $accessoryCheckoutId = null, $backto = null) : RedirectResponse
|
||||
{
|
||||
if (is_null($accessory_user = DB::table('accessories_users')->find($accessoryUserId))) {
|
||||
if (is_null($accessory_checkout = AccessoryCheckout::find($accessoryCheckoutId))) {
|
||||
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.does_not_exist'));
|
||||
}
|
||||
|
||||
$accessory = Accessory::find($accessory_user->accessory_id);
|
||||
$accessory = Accessory::find($accessory_checkout->accessory_id);
|
||||
|
||||
$this->authorize('checkin', $accessory);
|
||||
|
||||
|
@ -58,12 +60,12 @@ class AccessoryCheckinController extends Controller
|
|||
}
|
||||
|
||||
// Was the accessory updated?
|
||||
if (DB::table('accessories_users')->where('id', '=', $accessory_user->id)->delete()) {
|
||||
$return_to = e($accessory_user->assigned_to);
|
||||
if ($accessory_checkout->delete()) {
|
||||
event(new CheckoutableCheckedIn($accessory, $accessory_checkout->assignedTo, auth()->user(), $request->input('note'), $checkin_at));
|
||||
|
||||
event(new CheckoutableCheckedIn($accessory, User::find($return_to), auth()->user(), $request->input('note'), $checkin_at));
|
||||
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
||||
|
||||
return redirect()->route('accessories.show', $accessory->id)->with('success', trans('admin/accessories/message.checkin.success'));
|
||||
return redirect()->to(Helper::getRedirectOption($request, $accessory->id, 'Accessories'))->with('success', trans('admin/accessories/message.checkin.success'));
|
||||
}
|
||||
// Redirect to the accessory management page with error
|
||||
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.checkin.error'));
|
||||
|
|
|
@ -3,9 +3,12 @@
|
|||
namespace App\Http\Controllers\Accessories;
|
||||
|
||||
use App\Events\CheckoutableCheckedOut;
|
||||
use App\Helpers\Helper;
|
||||
use App\Http\Controllers\CheckInOutRequest;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\AccessoryCheckoutRequest;
|
||||
use App\Models\Accessory;
|
||||
use App\Models\AccessoryCheckout;
|
||||
use App\Models\User;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Http\Request;
|
||||
|
@ -15,6 +18,9 @@ use \Illuminate\Http\RedirectResponse;
|
|||
|
||||
class AccessoryCheckoutController extends Controller
|
||||
{
|
||||
|
||||
use CheckInOutRequest;
|
||||
|
||||
/**
|
||||
* Return the form to checkout an Accessory to a user.
|
||||
*
|
||||
|
@ -24,7 +30,7 @@ class AccessoryCheckoutController extends Controller
|
|||
public function create($id) : View | RedirectResponse
|
||||
{
|
||||
|
||||
if ($accessory = Accessory::withCount('users as users_count')->find($id)) {
|
||||
if ($accessory = Accessory::withCount('checkouts as checkouts_count')->find($id)) {
|
||||
|
||||
$this->authorize('checkout', $accessory);
|
||||
|
||||
|
@ -57,29 +63,38 @@ class AccessoryCheckoutController extends Controller
|
|||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param Request $request
|
||||
* @param int $accessory
|
||||
* @param Accessory $accessory
|
||||
*/
|
||||
public function store(AccessoryCheckoutRequest $request, Accessory $accessory) : RedirectResponse
|
||||
{
|
||||
|
||||
|
||||
$this->authorize('checkout', $accessory);
|
||||
$accessory->assigned_to = $request->input('assigned_to');
|
||||
$user = User::find($request->input('assigned_to'));
|
||||
$accessory->checkout_qty = $request->input('checkout_qty', 1);
|
||||
|
||||
$target = $this->determineCheckoutTarget();
|
||||
|
||||
$accessory->checkout_qty = $request->input('checkout_qty', 1);
|
||||
|
||||
for ($i = 0; $i < $accessory->checkout_qty; $i++) {
|
||||
$accessory->users()->attach($accessory->id, [
|
||||
AccessoryCheckout::create([
|
||||
'accessory_id' => $accessory->id,
|
||||
'created_at' => Carbon::now(),
|
||||
'user_id' => Auth::id(),
|
||||
'assigned_to' => $request->input('assigned_to'),
|
||||
'assigned_to' => $target->id,
|
||||
'assigned_type' => $target::class,
|
||||
'note' => $request->input('note'),
|
||||
]);
|
||||
}
|
||||
event(new CheckoutableCheckedOut($accessory, $user, auth()->user(), $request->input('note')));
|
||||
event(new CheckoutableCheckedOut($accessory, $target, auth()->user(), $request->input('note')));
|
||||
|
||||
// Set this as user since we only allow checkout to user for this item type
|
||||
$request->request->add(['checkout_to_type' => request('checkout_to_type')]);
|
||||
$request->request->add(['assigned_user' => $target->id]);
|
||||
|
||||
session()->put(['redirect_option' => $request->get('redirect_option'), 'checkout_to_type' => $request->get('checkout_to_type')]);
|
||||
|
||||
|
||||
// Redirect to the new accessory page
|
||||
return redirect()->route('accessories.index')
|
||||
return redirect()->to(Helper::getRedirectOption($request, $accessory->id, 'Accessories'))
|
||||
->with('success', trans('admin/accessories/message.checkout.success'));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ namespace App\Http\Controllers\Api;
|
|||
|
||||
use App\Events\CheckoutableCheckedOut;
|
||||
use App\Helpers\Helper;
|
||||
use App\Http\Controllers\CheckInOutRequest;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\AccessoryCheckoutRequest;
|
||||
use App\Http\Requests\StoreAccessoryRequest;
|
||||
|
@ -17,10 +18,12 @@ use Carbon\Carbon;
|
|||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Requests\ImageUploadRequest;
|
||||
|
||||
use App\Models\AccessoryCheckout;
|
||||
|
||||
class AccessoriesController extends Controller
|
||||
{
|
||||
use CheckInOutRequest;
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
|
@ -48,13 +51,13 @@ class AccessoriesController extends Controller
|
|||
'min_amt',
|
||||
'company_id',
|
||||
'notes',
|
||||
'users_count',
|
||||
'checkouts_count',
|
||||
'qty',
|
||||
];
|
||||
|
||||
|
||||
$accessories = Accessory::select('accessories.*')->with('category', 'company', 'manufacturer', 'users', 'location', 'supplier')
|
||||
->withCount('users as users_count');
|
||||
$accessories = Accessory::select('accessories.*')->with('category', 'company', 'manufacturer', 'checkouts', 'location', 'supplier')
|
||||
->withCount('checkouts as checkouts_count');
|
||||
|
||||
if ($request->filled('search')) {
|
||||
$accessories = $accessories->TextSearch($request->input('search'));
|
||||
|
@ -154,7 +157,7 @@ class AccessoriesController extends Controller
|
|||
public function show($id)
|
||||
{
|
||||
$this->authorize('view', Accessory::class);
|
||||
$accessory = Accessory::withCount('users as users_count')->findOrFail($id);
|
||||
$accessory = Accessory::withCount('checkouts as checkouts_count')->findOrFail($id);
|
||||
|
||||
return (new AccessoriesTransformer)->transformAccessory($accessory);
|
||||
}
|
||||
|
@ -197,28 +200,23 @@ class AccessoriesController extends Controller
|
|||
$offset = request('offset', 0);
|
||||
$limit = request('limit', 50);
|
||||
|
||||
$accessory_users = $accessory->users;
|
||||
$total = $accessory_users->count();
|
||||
$accessory_checkouts = $accessory->checkouts;
|
||||
$total = $accessory_checkouts->count();
|
||||
|
||||
if ($total < $offset) {
|
||||
$offset = 0;
|
||||
}
|
||||
|
||||
$accessory_users = $accessory->users()->skip($offset)->take($limit)->get();
|
||||
$accessory_checkouts = $accessory->checkouts()->skip($offset)->take($limit)->get();
|
||||
|
||||
if ($request->filled('search')) {
|
||||
$accessory_users = $accessory->users()
|
||||
->where(function ($query) use ($request) {
|
||||
$search_str = '%' . $request->input('search') . '%';
|
||||
$query->where('first_name', 'like', $search_str)
|
||||
->orWhere('last_name', 'like', $search_str)
|
||||
->orWhere('note', 'like', $search_str);
|
||||
})
|
||||
|
||||
$accessory_checkouts = $accessory->checkouts()->TextSearch($request->input('search'))
|
||||
->get();
|
||||
$total = $accessory_users->count();
|
||||
$total = $accessory_checkouts->count();
|
||||
}
|
||||
|
||||
return (new AccessoriesTransformer)->transformCheckedoutAccessory($accessory, $accessory_users, $total);
|
||||
return (new AccessoriesTransformer)->transformCheckedoutAccessory($accessory, $accessory_checkouts, $total);
|
||||
}
|
||||
|
||||
|
||||
|
@ -282,22 +280,22 @@ class AccessoriesController extends Controller
|
|||
public function checkout(AccessoryCheckoutRequest $request, Accessory $accessory)
|
||||
{
|
||||
$this->authorize('checkout', $accessory);
|
||||
$accessory->assigned_to = $request->input('assigned_to');
|
||||
$user = User::find($request->input('assigned_to'));
|
||||
$target = $this->determineCheckoutTarget();
|
||||
$accessory->checkout_qty = $request->input('checkout_qty', 1);
|
||||
|
||||
for ($i = 0; $i < $accessory->checkout_qty; $i++) {
|
||||
$accessory->users()->attach($accessory->id, [
|
||||
AccessoryCheckout::create([
|
||||
'accessory_id' => $accessory->id,
|
||||
'created_at' => Carbon::now(),
|
||||
'user_id' => Auth::id(),
|
||||
'assigned_to' => $request->input('assigned_to'),
|
||||
'assigned_to' => $target->id,
|
||||
'assigned_type' => $target::class,
|
||||
'note' => $request->input('note'),
|
||||
]);
|
||||
}
|
||||
|
||||
// Set this value to be able to pass the qty through to the event
|
||||
event(new CheckoutableCheckedOut($accessory, $user, auth()->user(), $request->input('note')));
|
||||
event(new CheckoutableCheckedOut($accessory, $target, auth()->user(), $request->input('note')));
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/accessories/message.checkout.success')));
|
||||
|
||||
|
@ -316,19 +314,19 @@ class AccessoriesController extends Controller
|
|||
*/
|
||||
public function checkin(Request $request, $accessoryUserId = null)
|
||||
{
|
||||
if (is_null($accessory_user = DB::table('accessories_users')->find($accessoryUserId))) {
|
||||
if (is_null($accessory_checkout = AccessoryCheckout::find($accessoryUserId))) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/accessories/message.does_not_exist')));
|
||||
}
|
||||
|
||||
$accessory = Accessory::find($accessory_user->accessory_id);
|
||||
$accessory = Accessory::find($accessory_checkout->accessory_id);
|
||||
$this->authorize('checkin', $accessory);
|
||||
|
||||
$logaction = $accessory->logCheckin(User::find($accessory_user->assigned_to), $request->input('note'));
|
||||
$logaction = $accessory->logCheckin(User::find($accessory_checkout->assigned_to), $request->input('note'));
|
||||
|
||||
// Was the accessory updated?
|
||||
if (DB::table('accessories_users')->where('id', '=', $accessory_user->id)->delete()) {
|
||||
if (! is_null($accessory_user->assigned_to)) {
|
||||
$user = User::find($accessory_user->assigned_to);
|
||||
if ($accessory_checkout->delete()) {
|
||||
if (! is_null($accessory_checkout->assigned_to)) {
|
||||
$user = User::find($accessory_checkout->assigned_to);
|
||||
}
|
||||
|
||||
$data['log_id'] = $logaction->id;
|
||||
|
|
|
@ -24,7 +24,7 @@ class LicensesController extends Controller
|
|||
{
|
||||
$this->authorize('view', License::class);
|
||||
|
||||
$licenses = License::with('company', 'manufacturer', 'supplier','category')->withCount('freeSeats as free_seats_count');
|
||||
$licenses = License::with('company', 'manufacturer', 'supplier','category', 'adminuser')->withCount('freeSeats as free_seats_count');
|
||||
|
||||
if ($request->filled('company_id')) {
|
||||
$licenses->where('company_id', '=', $request->input('company_id'));
|
||||
|
@ -70,6 +70,9 @@ class LicensesController extends Controller
|
|||
$licenses->where('depreciation_id', '=', $request->input('depreciation_id'));
|
||||
}
|
||||
|
||||
if ($request->filled('user_id')) {
|
||||
$licenses->where('user_id', '=', $request->input('user_id'));
|
||||
}
|
||||
|
||||
if (($request->filled('maintained')) && ($request->input('maintained')=='true')) {
|
||||
$licenses->where('maintained','=',1);
|
||||
|
@ -113,6 +116,9 @@ class LicensesController extends Controller
|
|||
case 'company':
|
||||
$licenses = $licenses->leftJoin('companies', 'licenses.company_id', '=', 'companies.id')->orderBy('companies.name', $order);
|
||||
break;
|
||||
case 'created_by':
|
||||
$licenses = $licenses->OrderCreatedBy($order);
|
||||
break;
|
||||
default:
|
||||
$allowed_columns =
|
||||
[
|
||||
|
|
|
@ -5,8 +5,10 @@ namespace App\Http\Controllers\Api;
|
|||
use App\Helpers\Helper;
|
||||
use App\Http\Requests\ImageUploadRequest;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Transformers\AssetsTransformer;
|
||||
use App\Http\Transformers\LocationsTransformer;
|
||||
use App\Http\Transformers\SelectlistTransformer;
|
||||
use App\Models\Asset;
|
||||
use App\Models\Location;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
|
@ -222,6 +224,15 @@ class LocationsController extends Controller
|
|||
return response()->json(Helper::formatStandardApiResponse('error', null, $location->getErrors()));
|
||||
}
|
||||
|
||||
public function assets(Request $request, Location $location) : JsonResponse | array
|
||||
{
|
||||
$this->authorize('view', Asset::class);
|
||||
$this->authorize('view', $location);
|
||||
$assets = Asset::where('assigned_to', '=', $location->id)->where('assigned_type', '=', Location::class)->with('model', 'model.category', 'assetstatus', 'location', 'company', 'defaultLoc');
|
||||
$assets = $assets->get();
|
||||
return (new AssetsTransformer)->transformAssets($assets, $assets->count(), $request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
|
|
|
@ -11,7 +11,6 @@ use App\Models\Asset;
|
|||
use App\Models\CheckoutAcceptance;
|
||||
use App\Models\LicenseSeat;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use \Illuminate\Contracts\View\View;
|
||||
use \Illuminate\Http\RedirectResponse;
|
||||
|
@ -83,7 +82,6 @@ class AssetCheckinController extends Controller
|
|||
}
|
||||
|
||||
$asset->expected_checkin = null;
|
||||
//$asset->last_checkout = null;
|
||||
$asset->last_checkin = now();
|
||||
$asset->assignedTo()->disassociate($asset);
|
||||
$asset->accepted = null;
|
||||
|
@ -128,12 +126,12 @@ class AssetCheckinController extends Controller
|
|||
$acceptance->delete();
|
||||
});
|
||||
|
||||
Session::put('redirect_option', $request->get('redirect_option'));
|
||||
// Was the asset updated?
|
||||
session()->put('redirect_option', $request->get('redirect_option'));
|
||||
|
||||
if ($asset->save()) {
|
||||
|
||||
event(new CheckoutableCheckedIn($asset, $target, auth()->user(), $request->input('note'), $checkin_at, $originalValues));
|
||||
return Helper::getRedirectOption($asset, $assetId, 'Assets');
|
||||
return redirect()->to(Helper::getRedirectOption($request, $asset->id, 'Assets'))->with('success', trans('admin/hardware/message.checkin.success'));
|
||||
}
|
||||
// Redirect to the asset management page with error
|
||||
return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.checkin.error').$asset->getErrors());
|
||||
|
|
|
@ -109,10 +109,11 @@ class AssetCheckoutController extends Controller
|
|||
}
|
||||
}
|
||||
|
||||
Session::put(['redirect_option' => $request->get('redirect_option'), 'checkout_to_type' => $request->get('checkout_to_type')]);
|
||||
session()->put(['redirect_option' => $request->get('redirect_option'), 'checkout_to_type' => $request->get('checkout_to_type')]);
|
||||
|
||||
if ($asset->checkOut($target, $admin, $checkout_at, $expected_checkin, $request->get('note'), $request->get('name'))) {
|
||||
return Helper::getRedirectOption($request, $assetId, 'Assets');
|
||||
return redirect()->to(Helper::getRedirectOption($request, $asset->id, 'Assets'))
|
||||
->with('success', trans('admin/hardware/message.checkout.success'));
|
||||
}
|
||||
// Redirect to the asset management page with error
|
||||
return redirect()->to("hardware/$assetId/checkout")->with('error', trans('admin/hardware/message.checkout.error').$asset->getErrors());
|
||||
|
|
|
@ -204,8 +204,12 @@ class AssetsController extends Controller
|
|||
}
|
||||
}
|
||||
|
||||
session()->put(['redirect_option' => $request->get('redirect_option'), 'checkout_to_type' => $request->get('checkout_to_type')]);
|
||||
|
||||
|
||||
if ($success) {
|
||||
return redirect()->route('hardware.index')
|
||||
|
||||
return redirect()->to(Helper::getRedirectOption($request, $asset->id, 'Assets'))
|
||||
->with('success-unescaped', trans('admin/hardware/message.create.success_linked', ['link' => route('hardware.show', ['hardware' => $asset->id]), 'id', 'tag' => e($asset->asset_tag)]));
|
||||
|
||||
|
||||
|
@ -289,6 +293,7 @@ class AssetsController extends Controller
|
|||
*/
|
||||
public function update(ImageUploadRequest $request, $assetId = null) : RedirectResponse
|
||||
{
|
||||
|
||||
// Check if the asset exists
|
||||
if (! $asset = Asset::find($assetId)) {
|
||||
// Redirect to the asset management page with error
|
||||
|
@ -331,7 +336,7 @@ class AssetsController extends Controller
|
|||
|
||||
$status = Statuslabel::find($asset->status_id);
|
||||
|
||||
if($status->archived){
|
||||
if ($status && $status->archived) {
|
||||
$asset->assigned_to = null;
|
||||
}
|
||||
|
||||
|
@ -350,14 +355,26 @@ class AssetsController extends Controller
|
|||
}
|
||||
|
||||
// Update the asset data
|
||||
$asset_tag = $request->input('asset_tags');
|
||||
|
||||
$serial = $request->input('serials');
|
||||
$asset->serial = $request->input('serials');
|
||||
|
||||
if (is_array($request->input('serials'))) {
|
||||
$asset->serial = $serial[1];
|
||||
}
|
||||
|
||||
$asset->name = $request->input('name');
|
||||
$asset->serial = $serial[1];
|
||||
$asset->company_id = Company::getIdForCurrentUser($request->input('company_id'));
|
||||
$asset->model_id = $request->input('model_id');
|
||||
$asset->order_number = $request->input('order_number');
|
||||
$asset->asset_tag = $asset_tag[1];
|
||||
|
||||
$asset_tags = $request->input('asset_tags');
|
||||
$asset->asset_tag = $request->input('asset_tags');
|
||||
|
||||
if (is_array($request->input('asset_tags'))) {
|
||||
$asset->asset_tag = $asset_tags[1];
|
||||
}
|
||||
|
||||
$asset->notes = $request->input('notes');
|
||||
|
||||
$asset = $request->handleImages($asset);
|
||||
|
@ -369,6 +386,7 @@ class AssetsController extends Controller
|
|||
$model = AssetModel::find($request->get('model_id'));
|
||||
if (($model) && ($model->fieldset)) {
|
||||
foreach ($model->fieldset->fields as $field) {
|
||||
|
||||
if ($field->field_encrypted == '1') {
|
||||
if (Gate::allows('admin')) {
|
||||
if (is_array($request->input($field->db_column))) {
|
||||
|
@ -387,9 +405,10 @@ class AssetsController extends Controller
|
|||
}
|
||||
}
|
||||
|
||||
session()->put(['redirect_option' => $request->get('redirect_option'), 'checkout_to_type' => $request->get('checkout_to_type')]);
|
||||
|
||||
if ($asset->save()) {
|
||||
return redirect()->route('hardware.show', $assetId)
|
||||
return redirect()->to(Helper::getRedirectOption($request, $assetId, 'Assets'))
|
||||
->with('success', trans('admin/hardware/message.update.success'));
|
||||
}
|
||||
|
||||
|
@ -459,9 +478,16 @@ class AssetsController extends Controller
|
|||
$tag = $tag ? $tag : $request->get('assetTag');
|
||||
$topsearch = ($request->get('topsearch') == 'true');
|
||||
|
||||
if (! $asset = Asset::where('asset_tag', '=', $tag)->first()) {
|
||||
return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.does_not_exist'));
|
||||
// Search for an exact and unique asset tag match
|
||||
$assets = Asset::where('asset_tag', '=', $tag);
|
||||
|
||||
// If not a unique result, redirect to the index view
|
||||
if ($assets->count() != 1) {
|
||||
return redirect()->route('hardware.index')
|
||||
->with('search', $tag)
|
||||
->with('warning', trans('admin/hardware/message.does_not_exist_var', [ 'asset_tag' => $tag ]));
|
||||
}
|
||||
$asset = $assets->first();
|
||||
$this->authorize('view', $asset);
|
||||
|
||||
return redirect()->route('hardware.show', $asset->id)->with('topsearch', $topsearch);
|
||||
|
|
|
@ -87,7 +87,7 @@ class ResetPasswordController extends Controller
|
|||
'password.not_in' => trans('validation.disallow_same_pwd_as_user_fields'),
|
||||
];
|
||||
|
||||
$request->validate($this->rules(), $request->all(), $this->validationErrorMessages());
|
||||
$request->validate($this->rules());
|
||||
|
||||
Log::debug('Checking if '.$request->input('username').' exists');
|
||||
// Check to see if the user even exists - we'll treat the response the same to prevent user sniffing
|
||||
|
|
|
@ -4,6 +4,7 @@ namespace App\Http\Controllers\Components;
|
|||
|
||||
use App\Events\CheckoutableCheckedIn;
|
||||
use App\Events\ComponentCheckedIn;
|
||||
use App\Helpers\Helper;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Asset;
|
||||
use App\Models\Component;
|
||||
|
@ -96,12 +97,10 @@ class ComponentCheckinController extends Controller
|
|||
$asset = Asset::find($component_assets->asset_id);
|
||||
|
||||
event(new CheckoutableCheckedIn($component, $asset, auth()->user(), $request->input('note'), Carbon::now()));
|
||||
if ($backto == 'asset'){
|
||||
return redirect()->route('hardware.show', $asset->id)->with('success',
|
||||
trans('admin/components/message.checkin.success'));
|
||||
}
|
||||
|
||||
return redirect()->route('components.index')->with('success',
|
||||
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
||||
|
||||
return redirect()->to(Helper::getRedirectOption($request, $component->id, 'Components'))->with('success',
|
||||
trans('admin/components/message.checkin.success'));
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ namespace App\Http\Controllers\Components;
|
|||
|
||||
use App\Events\CheckoutableCheckedOut;
|
||||
use App\Events\ComponentCheckedOut;
|
||||
use App\Helpers\Helper;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Asset;
|
||||
use App\Models\Component;
|
||||
|
@ -93,14 +94,14 @@ class ComponentCheckoutController extends Controller
|
|||
->withInput();
|
||||
}
|
||||
|
||||
// Check if the user exists
|
||||
// Check if the asset exists
|
||||
$asset = Asset::find($request->input('asset_id'));
|
||||
|
||||
// Update the component data
|
||||
$component->asset_id = $request->input('asset_id');
|
||||
$component->assets()->attach($component->id, [
|
||||
'component_id' => $component->id,
|
||||
'user_id' => auth()->user(),
|
||||
'user_id' => auth()->user()->id,
|
||||
'created_at' => date('Y-m-d H:i:s'),
|
||||
'assigned_qty' => $request->input('assigned_qty'),
|
||||
'asset_id' => $request->input('asset_id'),
|
||||
|
@ -109,6 +110,11 @@ class ComponentCheckoutController extends Controller
|
|||
|
||||
event(new CheckoutableCheckedOut($component, $asset, auth()->user(), $request->input('note')));
|
||||
|
||||
return redirect()->route('components.index')->with('success', trans('admin/components/message.checkout.success'));
|
||||
$request->request->add(['checkout_to_type' => 'asset']);
|
||||
$request->request->add(['assigned_asset' => $asset->id]);
|
||||
|
||||
session()->put(['redirect_option' => $request->get('redirect_option'), 'checkout_to_type' => $request->get('checkout_to_type')]);
|
||||
|
||||
return redirect()->to(Helper::getRedirectOption($request, $component->id, 'Components'))->with('success', trans('admin/components/message.checkout.success'));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -86,8 +86,10 @@ class ComponentsController extends Controller
|
|||
|
||||
$component = $request->handleImages($component);
|
||||
|
||||
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
||||
|
||||
if ($component->save()) {
|
||||
return redirect()->route('components.index')->with('success', trans('admin/components/message.create.success'));
|
||||
return redirect()->to(Helper::getRedirectOption($request, $component->id, 'Components'))->with('success', trans('admin/components/message.create.success'));
|
||||
}
|
||||
|
||||
return redirect()->back()->withInput()->withErrors($component->getErrors());
|
||||
|
@ -160,8 +162,10 @@ class ComponentsController extends Controller
|
|||
|
||||
$component = $request->handleImages($component);
|
||||
|
||||
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
||||
|
||||
if ($component->save()) {
|
||||
return redirect()->route('components.index')->with('success', trans('admin/components/message.update.success'));
|
||||
return redirect()->to(Helper::getRedirectOption($request, $component->id, 'Components'))->with('success', trans('admin/components/message.update.success'));
|
||||
}
|
||||
|
||||
return redirect()->back()->withInput()->withErrors($component->getErrors());
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
namespace App\Http\Controllers\Consumables;
|
||||
|
||||
use App\Events\CheckoutableCheckedOut;
|
||||
use App\Helpers\Helper;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Consumable;
|
||||
use App\Models\User;
|
||||
|
@ -33,7 +34,7 @@ class ConsumableCheckoutController extends Controller
|
|||
// Make sure there is at least one available to checkout
|
||||
if ($consumable->numRemaining() <= 0){
|
||||
return redirect()->route('consumables.index')
|
||||
->with('error', trans('admin/consumables/message.checkout.unavailable'));
|
||||
->with('error', trans('admin/consumables/message.checkout.unavailable', ['requested' => 1, 'remaining' => $consumable->numRemaining()]));
|
||||
}
|
||||
|
||||
// Return the checkout view
|
||||
|
@ -76,7 +77,7 @@ class ConsumableCheckoutController extends Controller
|
|||
|
||||
// Make sure there is at least one available to checkout
|
||||
if ($consumable->numRemaining() <= 0 || $quantity > $consumable->numRemaining()) {
|
||||
return redirect()->route('consumables.index')->with('error', trans('admin/consumables/message.checkout.unavailable'));
|
||||
return redirect()->route('consumables.index')->with('error', trans('admin/consumables/message.checkout.unavailable', ['requested' => $quantity, 'remaining' => $consumable->numRemaining() ]));
|
||||
}
|
||||
|
||||
$admin_user = auth()->user();
|
||||
|
@ -101,7 +102,13 @@ class ConsumableCheckoutController extends Controller
|
|||
}
|
||||
event(new CheckoutableCheckedOut($consumable, $user, auth()->user(), $request->input('note')));
|
||||
|
||||
$request->request->add(['checkout_to_type' => 'user']);
|
||||
$request->request->add(['assigned_user' => $user->id]);
|
||||
|
||||
session()->put(['redirect_option' => $request->get('redirect_option'), 'checkout_to_type' => $request->get('checkout_to_type')]);
|
||||
|
||||
|
||||
// Redirect to the new consumable page
|
||||
return redirect()->route('consumables.index')->with('success', trans('admin/consumables/message.checkout.success'));
|
||||
return redirect()->to(Helper::getRedirectOption($request, $consumable->id, 'Consumables'))->with('success', trans('admin/consumables/message.checkout.success'));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -87,8 +87,10 @@ class ConsumablesController extends Controller
|
|||
|
||||
$consumable = $request->handleImages($consumable);
|
||||
|
||||
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
||||
|
||||
if ($consumable->save()) {
|
||||
return redirect()->route('consumables.index')->with('success', trans('admin/consumables/message.create.success'));
|
||||
return redirect()->to(Helper::getRedirectOption($request, $consumable->id, 'Consumables'))->with('success', trans('admin/consumables/message.create.success'));
|
||||
}
|
||||
|
||||
return redirect()->back()->withInput()->withErrors($consumable->getErrors());
|
||||
|
@ -160,8 +162,10 @@ class ConsumablesController extends Controller
|
|||
|
||||
$consumable = $request->handleImages($consumable);
|
||||
|
||||
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
||||
|
||||
if ($consumable->save()) {
|
||||
return redirect()->route('consumables.index')->with('success', trans('admin/consumables/message.update.success'));
|
||||
return redirect()->to(Helper::getRedirectOption($request, $consumable->id, 'Consumables'))->with('success', trans('admin/consumables/message.update.success'));
|
||||
}
|
||||
|
||||
return redirect()->back()->withInput()->withErrors($consumable->getErrors());
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
namespace App\Http\Controllers\Licenses;
|
||||
|
||||
use App\Events\CheckoutableCheckedIn;
|
||||
use App\Helpers\Helper;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\License;
|
||||
use App\Models\LicenseSeat;
|
||||
|
@ -100,15 +101,15 @@ class LicenseCheckinController extends Controller
|
|||
$licenseSeat->asset_id = null;
|
||||
$licenseSeat->notes = $request->input('notes');
|
||||
|
||||
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
||||
|
||||
|
||||
// Was the asset updated?
|
||||
if ($licenseSeat->save()) {
|
||||
event(new CheckoutableCheckedIn($licenseSeat, $return_to, auth()->user(), $request->input('notes')));
|
||||
|
||||
if ($backTo == 'user') {
|
||||
return redirect()->route('users.show', $return_to->id)->with('success', trans('admin/licenses/message.checkin.success'));
|
||||
}
|
||||
|
||||
return redirect()->route('licenses.show', $licenseSeat->license_id)->with('success', trans('admin/licenses/message.checkin.success'));
|
||||
return redirect()->to(Helper::getRedirectOption($request, $license->id, 'Licenses'))->with('success', trans('admin/licenses/message.checkin.success'));
|
||||
}
|
||||
|
||||
// Redirect to the license page with error
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
namespace App\Http\Controllers\Licenses;
|
||||
|
||||
use App\Events\CheckoutableCheckedOut;
|
||||
use App\Helpers\Helper;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\LicenseCheckoutRequest;
|
||||
use App\Models\Accessory;
|
||||
|
@ -81,10 +82,27 @@ class LicenseCheckoutController extends Controller
|
|||
|
||||
|
||||
$checkoutMethod = 'checkoutTo'.ucwords(request('checkout_to_type'));
|
||||
if ($this->$checkoutMethod($licenseSeat)) {
|
||||
return redirect()->route('licenses.index')->with('success', trans('admin/licenses/message.checkout.success'));
|
||||
|
||||
if ($request->filled('asset_id')) {
|
||||
|
||||
$checkoutTarget = $this->checkoutToAsset($licenseSeat);
|
||||
$request->request->add(['assigned_asset' => $checkoutTarget->id]);
|
||||
session()->put(['redirect_option' => $request->get('redirect_option'), 'checkout_to_type' => 'asset']);
|
||||
|
||||
} elseif ($request->filled('assigned_to')) {
|
||||
$checkoutTarget = $this->checkoutToUser($licenseSeat);
|
||||
$request->request->add(['assigned_user' => $checkoutTarget->id]);
|
||||
session()->put(['redirect_option' => $request->get('redirect_option'), 'checkout_to_type' => 'user']);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if ($checkoutTarget) {
|
||||
return redirect()->to(Helper::getRedirectOption($request, $license->id, 'Licenses'))->with('success', trans('admin/licenses/message.checkout.success'));
|
||||
}
|
||||
|
||||
|
||||
|
||||
return redirect()->route('licenses.index')->with('error', trans('Something went wrong handling this checkout.'));
|
||||
}
|
||||
|
||||
|
@ -120,8 +138,7 @@ class LicenseCheckoutController extends Controller
|
|||
}
|
||||
if ($licenseSeat->save()) {
|
||||
event(new CheckoutableCheckedOut($licenseSeat, $target, auth()->user(), request('notes')));
|
||||
|
||||
return true;
|
||||
return $target;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -137,8 +154,7 @@ class LicenseCheckoutController extends Controller
|
|||
|
||||
if ($licenseSeat->save()) {
|
||||
event(new CheckoutableCheckedOut($licenseSeat, $target, auth()->user(), request('notes')));
|
||||
|
||||
return true;
|
||||
return $target;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
|
@ -102,8 +102,10 @@ class LicensesController extends Controller
|
|||
$license->user_id = Auth::id();
|
||||
$license->min_amt = $request->input('min_amt');
|
||||
|
||||
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
||||
|
||||
if ($license->save()) {
|
||||
return redirect()->route('licenses.index')->with('success', trans('admin/licenses/message.create.success'));
|
||||
return redirect()->to(Helper::getRedirectOption($request, $license->id, 'Licenses'))->with('success', trans('admin/licenses/message.create.success'));
|
||||
}
|
||||
|
||||
return redirect()->back()->withInput()->withErrors($license->getErrors());
|
||||
|
@ -180,8 +182,10 @@ class LicensesController extends Controller
|
|||
$license->category_id = $request->input('category_id');
|
||||
$license->min_amt = $request->input('min_amt');
|
||||
|
||||
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
||||
|
||||
if ($license->save()) {
|
||||
return redirect()->route('licenses.show', ['license' => $licenseId])->with('success', trans('admin/licenses/message.update.success'));
|
||||
return redirect()->to(Helper::getRedirectOption($request, $license->id, 'Licenses'))->with('success', trans('admin/licenses/message.update.success'));
|
||||
}
|
||||
// If we can't adjust the number of seats, the error is flashed to the session by the event handler in License.php
|
||||
return redirect()->back()->withInput()->withErrors($license->getErrors());
|
||||
|
|
|
@ -1255,7 +1255,7 @@ class SettingsController extends Controller
|
|||
DB::table('users')->update(['remember_token' => null]);
|
||||
Auth::logout();
|
||||
|
||||
return redirect()->route('login')->with('success', 'Your system has been restored. Please login again.');
|
||||
return redirect()->route('login')->with('success', trans('admin/settings/message.restore.success'));
|
||||
} else {
|
||||
return redirect()->route('settings.backups.index')->with('error', trans('admin/settings/message.backup.file_not_found'));
|
||||
}
|
||||
|
|
|
@ -220,7 +220,7 @@ class BulkUsersController extends Controller
|
|||
|
||||
$users = User::whereIn('id', $user_raw_array)->get();
|
||||
$assets = Asset::whereIn('assigned_to', $user_raw_array)->where('assigned_type', \App\Models\User::class)->get();
|
||||
$accessoryUserRows = DB::table('accessories_users')->whereIn('assigned_to', $user_raw_array)->get();
|
||||
$accessoryUserRows = DB::table('accessories_checkout')->whereIn('assigned_to', $user_raw_array)->where('assigned_type', \App\Models\User::class)->get();
|
||||
$licenses = DB::table('license_seats')->whereIn('assigned_to', $user_raw_array)->get();
|
||||
$consumableUserRows = DB::table('consumables_users')->whereIn('assigned_to', $user_raw_array)->get();
|
||||
|
||||
|
|
|
@ -133,6 +133,8 @@ class UsersController extends Controller
|
|||
// we have to invoke the
|
||||
app(ImageUploadRequest::class)->handleImages($user, 600, 'avatar', 'avatars', 'avatar');
|
||||
|
||||
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
||||
|
||||
if ($user->save()) {
|
||||
if ($request->filled('groups')) {
|
||||
$user->groups()->sync($request->input('groups'));
|
||||
|
@ -152,7 +154,7 @@ class UsersController extends Controller
|
|||
$user->notify(new WelcomeNotification($data));
|
||||
}
|
||||
|
||||
return redirect()->route('users.index')->with('success', trans('admin/users/message.success.create'));
|
||||
return redirect()->to(Helper::getRedirectOption($request, $user->id, 'Users'))->with('success', trans('admin/users/message.success.create'));
|
||||
}
|
||||
|
||||
return redirect()->back()->withInput()->withErrors($user->getErrors());
|
||||
|
@ -309,10 +311,11 @@ class UsersController extends Controller
|
|||
|
||||
// Handle uploaded avatar
|
||||
app(ImageUploadRequest::class)->handleImages($user, 600, 'avatar', 'avatars', 'avatar');
|
||||
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
||||
|
||||
if ($user->save()) {
|
||||
// Redirect to the user page
|
||||
return redirect()->route('users.index')
|
||||
return redirect()->to(Helper::getRedirectOption($request, $user->id, 'Users'))
|
||||
->with('success', trans('admin/users/message.success.update'));
|
||||
}
|
||||
|
||||
|
|
|
@ -44,13 +44,10 @@ class AccessoryCheckoutRequest extends ImageUploadRequest
|
|||
|
||||
return array_merge(
|
||||
[
|
||||
'assigned_to' => [
|
||||
'required',
|
||||
'integer',
|
||||
'exists:users,id,deleted_at,NULL',
|
||||
'not_array'
|
||||
],
|
||||
|
||||
'assigned_user' => 'required_without_all:assigned_asset,assigned_location',
|
||||
'assigned_asset' => 'required_without_all:assigned_user,assigned_location',
|
||||
'assigned_location' => 'required_without_all:assigned_user,assigned_asset',
|
||||
|
||||
'number_remaining_after_checkout' => [
|
||||
'min:0',
|
||||
'required',
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use App\Http\Requests\Traits\MayContainCustomFields;
|
||||
use App\Models\Asset;
|
||||
use App\Models\Company;
|
||||
use App\Models\Setting;
|
||||
|
@ -11,6 +12,7 @@ use Illuminate\Support\Facades\Gate;
|
|||
|
||||
class StoreAssetRequest extends ImageUploadRequest
|
||||
{
|
||||
use MayContainCustomFields;
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
|
|
40
app/Http/Requests/Traits/MayContainCustomFields.php
Normal file
40
app/Http/Requests/Traits/MayContainCustomFields.php
Normal file
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Traits;
|
||||
|
||||
use App\Models\AssetModel;
|
||||
use App\Models\CustomField;
|
||||
|
||||
trait MayContainCustomFields
|
||||
{
|
||||
// this gets called automatically on a form request
|
||||
public function withValidator($validator)
|
||||
{
|
||||
// find the model
|
||||
if ($this->method() == 'POST') {
|
||||
$asset_model = AssetModel::find($this->model_id);
|
||||
}
|
||||
if ($this->method() == 'PATCH' || $this->method() == 'PUT') {
|
||||
// this is dependent on the asset update request PR
|
||||
$asset_model = $this->asset;
|
||||
}
|
||||
// collect the custom fields in the request
|
||||
$validator->after(function ($validator) use ($asset_model) {
|
||||
$request_fields = $this->collect()->keys()->filter(function ($attributes) {
|
||||
return str_starts_with($attributes, '_snipeit_');
|
||||
});
|
||||
// if there are custom fields, find the one's that don't exist on the model's fieldset and add an error to the validator's error bag
|
||||
if (count($request_fields) > 0) {
|
||||
$request_fields->diff($asset_model->fieldset->fields->pluck('db_column'))
|
||||
->each(function ($request_field_name) use ($request_fields, $validator) {
|
||||
if (CustomField::where('db_column', $request_field_name)->exists()) {
|
||||
$validator->errors()->add($request_field_name, trans('validation.custom.custom_field_not_found_on_model'));
|
||||
} else {
|
||||
$validator->errors()->add($request_field_name, trans('validation.custom.custom_field_not_found'));
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -39,7 +39,7 @@ class AccessoriesTransformer
|
|||
'order_number' => ($accessory->order_number) ? e($accessory->order_number) : null,
|
||||
'min_qty' => ($accessory->min_amt) ? (int) $accessory->min_amt : null,
|
||||
'remaining_qty' => (int) $accessory->numRemaining(),
|
||||
'users_count' => $accessory->users_count,
|
||||
'checkouts_count' => $accessory->checkouts_count,
|
||||
|
||||
'created_at' => Helper::getFormattedDateObject($accessory->created_at, 'datetime'),
|
||||
'updated_at' => Helper::getFormattedDateObject($accessory->updated_at, 'datetime'),
|
||||
|
@ -66,27 +66,42 @@ class AccessoriesTransformer
|
|||
return $array;
|
||||
}
|
||||
|
||||
public function transformCheckedoutAccessory($accessory, $accessory_users, $total)
|
||||
public function transformCheckedoutAccessory($accessory, $accessory_checkouts, $total)
|
||||
{
|
||||
$array = [];
|
||||
|
||||
foreach ($accessory_users as $user) {
|
||||
foreach ($accessory_checkouts as $checkout) {
|
||||
$array[] = [
|
||||
|
||||
'assigned_pivot_id' => $user->pivot->id,
|
||||
'id' => (int) $user->id,
|
||||
'username' => e($user->username),
|
||||
'name' => e($user->getFullNameAttribute()),
|
||||
'first_name'=> e($user->first_name),
|
||||
'last_name'=> e($user->last_name),
|
||||
'employee_number' => e($user->employee_num),
|
||||
'checkout_notes' => e($user->pivot->note),
|
||||
'last_checkout' => Helper::getFormattedDateObject($user->pivot->created_at, 'datetime'),
|
||||
'type' => 'user',
|
||||
'id' => $checkout->id,
|
||||
'assigned_to' => $this->transformAssignedTo($checkout),
|
||||
'checkout_notes' => e($checkout->note),
|
||||
'last_checkout' => Helper::getFormattedDateObject($checkout->created_at, 'datetime'),
|
||||
'available_actions' => ['checkin' => true],
|
||||
];
|
||||
}
|
||||
|
||||
return (new DatatablesTransformer)->transformDatatables($array, $total);
|
||||
}
|
||||
|
||||
public function transformAssignedTo($accessoryCheckout)
|
||||
{
|
||||
if ($accessoryCheckout->checkedOutToUser()) {
|
||||
return [
|
||||
'id' => (int) $accessoryCheckout->assigned->id,
|
||||
'username' => e($accessoryCheckout->assigned->username),
|
||||
'name' => e($accessoryCheckout->assigned->getFullNameAttribute()),
|
||||
'first_name'=> e($accessoryCheckout->assigned->first_name),
|
||||
'last_name'=> ($accessoryCheckout->assigned->last_name) ? e($accessoryCheckout->assigned->last_name) : null,
|
||||
'email'=> ($accessoryCheckout->assigned->email) ? e($accessoryCheckout->assigned->email) : null,
|
||||
'employee_number' => ($accessoryCheckout->assigned->employee_num) ? e($accessoryCheckout->assigned->employee_num) : null,
|
||||
'type' => 'user',
|
||||
];
|
||||
}
|
||||
|
||||
return $accessoryCheckout->assigned ? [
|
||||
'id' => $accessoryCheckout->assigned->id,
|
||||
'name' => e($accessoryCheckout->assigned->display_name),
|
||||
'type' => $accessoryCheckout->assignedType(),
|
||||
] : null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -205,11 +205,11 @@ class ActionlogsTransformer
|
|||
|
||||
|
||||
|
||||
public function transformCheckedoutActionlog (Collection $accessories_users, $total)
|
||||
public function transformCheckedoutActionlog (Collection $accessories_checkout, $total)
|
||||
{
|
||||
|
||||
$array = array();
|
||||
foreach ($accessories_users as $user) {
|
||||
foreach ($accessories_checkout as $user) {
|
||||
$array[] = (new UsersTransformer)->transformUser($user);
|
||||
}
|
||||
return (new DatatablesTransformer)->transformDatatables($array, $total);
|
||||
|
|
|
@ -45,6 +45,10 @@ class LicensesTransformer
|
|||
'maintained' => ($license->maintained == 1) ? true : false,
|
||||
'supplier' => ($license->supplier) ? ['id' => (int) $license->supplier->id, 'name'=> e($license->supplier->name)] : null,
|
||||
'category' => ($license->category) ? ['id' => (int) $license->category->id, 'name'=> e($license->category->name)] : null,
|
||||
'created_by' => ($license->adminuser) ? [
|
||||
'id' => (int) $license->adminuser->id,
|
||||
'name'=> e($license->adminuser->present()->fullName()),
|
||||
] : null,
|
||||
'created_at' => Helper::getFormattedDateObject($license->created_at, 'datetime'),
|
||||
'updated_at' => Helper::getFormattedDateObject($license->updated_at, 'datetime'),
|
||||
'deleted_at' => Helper::getFormattedDateObject($license->deleted_at, 'datetime'),
|
||||
|
|
|
@ -253,9 +253,10 @@ class Accessory extends SnipeModel
|
|||
* @since [v3.0]
|
||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||
*/
|
||||
public function users()
|
||||
public function checkouts()
|
||||
{
|
||||
return $this->belongsToMany(\App\Models\User::class, 'accessories_users', 'accessory_id', 'assigned_to')->withPivot('id', 'created_at', 'note')->withTrashed();
|
||||
return $this->hasMany(\App\Models\AccessoryCheckout::class, 'accessory_id')
|
||||
->with('assignedTo');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -267,7 +268,9 @@ class Accessory extends SnipeModel
|
|||
*/
|
||||
public function hasUsers()
|
||||
{
|
||||
return $this->belongsToMany(\App\Models\User::class, 'accessories_users', 'accessory_id', 'assigned_to')->count();
|
||||
return $this->hasMany(\App\Models\AccessoryCheckout::class, 'accessory_id')
|
||||
->where('assigned_type', User::class)
|
||||
->count();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -338,15 +341,15 @@ class Accessory extends SnipeModel
|
|||
*/
|
||||
public function numCheckedOut()
|
||||
{
|
||||
return $this->users_count ?? $this->users()->count();
|
||||
return $this->checkouts_count ?? $this->checkouts()->count();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check how many items of an accessory remain.
|
||||
*
|
||||
* In order to use this model method, you MUST call withCount('users as users_count')
|
||||
* on the eloquent query in the controller, otherwise $this->users_count will be null and
|
||||
* In order to use this model method, you MUST call withCount('checkouts as checkouts_count')
|
||||
* on the eloquent query in the controller, otherwise $this->checkouts_count will be null and
|
||||
* bad things happen.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
|
@ -370,12 +373,12 @@ class Accessory extends SnipeModel
|
|||
*/
|
||||
public function declinedCheckout(User $declinedBy, $signature)
|
||||
{
|
||||
if (is_null($accessory_user = \DB::table('accessories_users')->where('assigned_to', $declinedBy->id)->where('accessory_id', $this->id)->latest('created_at'))) {
|
||||
if (is_null($accessory_checkout = AccessoryCheckout::userAssigned()->where('assigned_to', $declinedBy->id)->where('accessory_id', $this->id)->latest('created_at'))) {
|
||||
// Redirect to the accessory management page with error
|
||||
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.does_not_exist'));
|
||||
}
|
||||
|
||||
$accessory_user->limit(1)->delete();
|
||||
$accessory_checkout->limit(1)->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
148
app/Models/AccessoryCheckout.php
Executable file
148
app/Models/AccessoryCheckout.php
Executable file
|
@ -0,0 +1,148 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Helpers\Helper;
|
||||
use App\Models\Traits\Acceptable;
|
||||
use App\Models\Traits\Searchable;
|
||||
use App\Presenters\Presentable;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Watson\Validating\ValidatingTrait;
|
||||
|
||||
/**
|
||||
* Model for Accessories.
|
||||
*
|
||||
* @version v1.0
|
||||
*/
|
||||
class AccessoryCheckout extends Model
|
||||
{
|
||||
use Searchable;
|
||||
|
||||
protected $fillable = ['user_id', 'accessory_id', 'assigned_to', 'assigned_type', 'note'];
|
||||
protected $table = 'accessories_checkout';
|
||||
|
||||
/**
|
||||
* Establishes the accessory checkout -> accessory relationship
|
||||
*
|
||||
* @author [A. Kroeger]
|
||||
* @since [v7.0.9]
|
||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||
*/
|
||||
public function accessory()
|
||||
{
|
||||
return $this->hasOne(\App\Models\Accessory::class, 'accessory_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Establishes the accessory checkout -> user relationship
|
||||
*
|
||||
* @author [A. Kroeger]
|
||||
* @since [v7.0.9]
|
||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||
*/
|
||||
public function user()
|
||||
{
|
||||
return $this->hasOne(\App\Models\User::class, 'user_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the target this asset is checked out to
|
||||
*
|
||||
* @author [A. Kroeger]
|
||||
* @since [v7.0]
|
||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||
*/
|
||||
public function assignedTo()
|
||||
{
|
||||
return $this->morphTo('assigned', 'assigned_type', 'assigned_to')->withTrashed();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the lowercased name of the type of target the asset is assigned to
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @return string
|
||||
*/
|
||||
public function assignedType()
|
||||
{
|
||||
return $this->assigned_type ? strtolower(class_basename($this->assigned_type)) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the accessory is checked out to a user
|
||||
*
|
||||
* Even though we allow allow for checkout to things beyond users
|
||||
* this method is an easy way of seeing if we are checked out to a user.
|
||||
*
|
||||
* @author [A. Kroeger]
|
||||
* @since [v7.0]
|
||||
*/
|
||||
public function checkedOutToUser(): bool
|
||||
{
|
||||
return $this->assignedType() === Asset::USER;
|
||||
}
|
||||
|
||||
public function scopeUserAssigned(Builder $query): void
|
||||
{
|
||||
$query->where('assigned_type', '=', User::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Run additional, advanced searches.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
* @param array $terms The search terms
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
public function advancedTextSearch(Builder $query, array $terms)
|
||||
{
|
||||
|
||||
$userQuery = User::where(function ($query) use ($terms) {
|
||||
foreach ($terms as $term) {
|
||||
$search_str = '%' . $term . '%';
|
||||
$query->where('first_name', 'like', $search_str)
|
||||
->orWhere('last_name', 'like', $search_str)
|
||||
->orWhere('note', 'like', $search_str);
|
||||
}
|
||||
})->select('id');
|
||||
|
||||
$locationQuery = Location::where(function ($query) use ($terms) {
|
||||
foreach ($terms as $term) {
|
||||
$search_str = '%' . $term . '%';
|
||||
$query->where('name', 'like', $search_str);
|
||||
}
|
||||
})->select('id');
|
||||
|
||||
$assetQuery = Asset::where(function ($query) use ($terms) {
|
||||
foreach ($terms as $term) {
|
||||
$search_str = '%' . $term . '%';
|
||||
$query->where('name', 'like', $search_str);
|
||||
}
|
||||
})->select('id');
|
||||
|
||||
$query->where(function ($query) use ($userQuery) {
|
||||
$query->where('assigned_type', User::class)
|
||||
->whereIn('assigned_to', $userQuery);
|
||||
})->orWhere(function($query) use ($locationQuery) {
|
||||
$query->where('assigned_type', Location::class)
|
||||
->whereIn('assigned_to', $locationQuery);
|
||||
})->orWhere(function($query) use ($assetQuery) {
|
||||
$query->where('assigned_type', Asset::class)
|
||||
->whereIn('assigned_to', $assetQuery);
|
||||
})->orWhere(function($query) use ($terms) {
|
||||
foreach ($terms as $term) {
|
||||
$search_str = '%' . $term . '%';
|
||||
$query->where('note', 'like', $search_str);
|
||||
}
|
||||
});
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -7,7 +7,7 @@ use EasySlugger\Utf8Slugger;
|
|||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Schema;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Watson\Validating\ValidatingTrait;
|
||||
class CustomField extends Model
|
||||
{
|
||||
|
|
|
@ -158,17 +158,20 @@ class Depreciable extends SnipeModel
|
|||
|
||||
public function time_until_depreciated()
|
||||
{
|
||||
// @link http://www.php.net/manual/en/class.datetime.php
|
||||
$d1 = new \DateTime();
|
||||
$d2 = $this->depreciated_date();
|
||||
if ($this->depreciated_date()) {
|
||||
// @link http://www.php.net/manual/en/class.datetime.php
|
||||
$d1 = new \DateTime();
|
||||
$d2 = $this->depreciated_date();
|
||||
|
||||
// @link http://www.php.net/manual/en/class.dateinterval.php
|
||||
$interval = $d1->diff($d2);
|
||||
if (! $interval->invert) {
|
||||
return $interval;
|
||||
} else {
|
||||
return new \DateInterval('PT0S'); //null interval (zero seconds from now)
|
||||
// @link http://www.php.net/manual/en/class.dateinterval.php
|
||||
$interval = $d1->diff($d2);
|
||||
if (! $interval->invert) {
|
||||
return $interval;
|
||||
} else {
|
||||
return new \DateInterval('PT0S'); //null interval (zero seconds from now)
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function depreciated_date()
|
||||
|
|
|
@ -50,7 +50,7 @@ class License extends Depreciable
|
|||
'category_id' => 'required|exists:categories,id',
|
||||
'company_id' => 'integer|nullable',
|
||||
'purchase_cost'=> 'numeric|nullable|gte:0',
|
||||
'purchase_date' => 'date_format:Y-m-d|nullable|max:10',
|
||||
'purchase_date' => 'date_format:Y-m-d|nullable|max:10|required_with:depreciation_id',
|
||||
'expiration_date' => 'date_format:Y-m-d|nullable|max:10',
|
||||
'termination_date' => 'date_format:Y-m-d|nullable|max:10',
|
||||
'min_amt' => 'numeric|nullable|gte:0',
|
||||
|
@ -736,4 +736,17 @@ class License extends Depreciable
|
|||
return $query->leftJoin('companies as companies', 'licenses.company_id', '=', 'companies.id')->select('licenses.*')
|
||||
->orderBy('companies.name', $order);
|
||||
}
|
||||
|
||||
/**
|
||||
* Query builder scope to order on the user that created it
|
||||
*
|
||||
* @param \Illuminate\Database\Query\Builder $query Query builder instance
|
||||
* @param text $order Order
|
||||
*
|
||||
* @return \Illuminate\Database\Query\Builder Modified query builder
|
||||
*/
|
||||
public function scopeOrderCreatedBy($query, $order)
|
||||
{
|
||||
return $query->leftJoin('users as users_sort', 'licenses.user_id', '=', 'users_sort.id')->select('licenses.*')->orderBy('users_sort.first_name', $order)->orderBy('users_sort.last_name', $order);
|
||||
}
|
||||
}
|
|
@ -331,7 +331,7 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
|
|||
*/
|
||||
public function accessories()
|
||||
{
|
||||
return $this->belongsToMany(\App\Models\Accessory::class, 'accessories_users', 'assigned_to', 'accessory_id')
|
||||
return $this->belongsToMany(\App\Models\Accessory::class, 'accessories_checkout', 'assigned_to', 'accessory_id')
|
||||
->withPivot('id', 'created_at', 'note')->withTrashed()->orderBy('accessory_id');
|
||||
}
|
||||
|
||||
|
|
|
@ -90,7 +90,7 @@ class AccessoryPresenter extends Presenter
|
|||
'visible' => false,
|
||||
'title' => trans('admin/accessories/general.remaining'),
|
||||
],[
|
||||
'field' => 'users_count',
|
||||
'field' => 'checkouts_count',
|
||||
'searchable' => false,
|
||||
'sortable' => true,
|
||||
'visible' => true,
|
||||
|
|
|
@ -158,6 +158,13 @@ class LicensePresenter extends Presenter
|
|||
'sortable' => true,
|
||||
'visible' => false,
|
||||
'title' => trans('general.order_number'),
|
||||
], [
|
||||
'field' => 'created_by',
|
||||
'searchable' => false,
|
||||
'sortable' => true,
|
||||
'title' => trans('general.admin'),
|
||||
'visible' => false,
|
||||
'formatter' => 'usersLinkObjFormatter',
|
||||
], [
|
||||
'field' => 'created_at',
|
||||
'searchable' => false,
|
||||
|
|
25
app/Providers/BladeServiceProvider.php
Normal file
25
app/Providers/BladeServiceProvider.php
Normal file
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Support\Facades\Blade;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
class BladeServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Register services.
|
||||
*/
|
||||
public function register(): void
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Bootstrap services.
|
||||
*/
|
||||
public function boot(): void
|
||||
{
|
||||
Blade::anonymousComponentPath(__DIR__ . '/../../resources/views/blade');
|
||||
}
|
||||
}
|
|
@ -10,7 +10,7 @@ use Illuminate\Support\Facades\Crypt;
|
|||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Validator;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
|
||||
/**
|
||||
* This service provider handles a few custom validation rules.
|
||||
|
|
|
@ -107,7 +107,7 @@ class Label implements View
|
|||
|
||||
if ($settings->alt_barcode_enabled) {
|
||||
if ($template->getSupport1DBarcode()) {
|
||||
$barcode1DType = $settings->alt_barcode;
|
||||
$barcode1DType = $settings->label2_1d_type;
|
||||
if ($barcode1DType != 'none') {
|
||||
$assetData->put('barcode1d', (object)[
|
||||
'type' => $barcode1DType,
|
||||
|
|
|
@ -313,6 +313,7 @@ return [
|
|||
/*
|
||||
* Custom Service Providers...
|
||||
*/
|
||||
App\Providers\BladeServiceProvider::class,
|
||||
App\Providers\LivewireServiceProvider::class,
|
||||
App\Providers\MacroServiceProvider::class,
|
||||
App\Providers\SamlServiceProvider::class,
|
||||
|
|
|
@ -44,12 +44,6 @@ return [
|
|||
'secret' => env('STRIPE_SECRET'),
|
||||
],
|
||||
|
||||
'baremetrics' => [
|
||||
'enabled' => env('ENABLE_BMPAY', false),
|
||||
'app_key' => env('BMPAY_PUBLIC_KEY', null),
|
||||
'stripe_id' => env('BMPAY_STRIPE_ID', null),
|
||||
],
|
||||
|
||||
'google' => [
|
||||
'maps_api_key' => env('GOOGLE_MAPS_API'),
|
||||
],
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
<?php
|
||||
return array (
|
||||
'app_version' => 'v7.0.9',
|
||||
'full_app_version' => 'v7.0.9 - build 14485-ga98ad76c6',
|
||||
'build_version' => '14485',
|
||||
'app_version' => 'v7.0.10',
|
||||
'full_app_version' => 'v7.0.10 - build 14684-gc2bcc2e2d',
|
||||
'build_version' => '14684',
|
||||
'prerelease_version' => '',
|
||||
'hash_version' => 'ga98ad76c6',
|
||||
'full_hash' => 'v7.0.9-112-ga98ad76c6',
|
||||
'hash_version' => 'gc2bcc2e2d',
|
||||
'full_hash' => 'v7.0.10-311-gc2bcc2e2d',
|
||||
'branch' => 'develop',
|
||||
);
|
|
@ -3,6 +3,7 @@
|
|||
namespace Database\Factories;
|
||||
|
||||
use App\Models\Accessory;
|
||||
use App\Models\AccessoryCheckout;
|
||||
use App\Models\Category;
|
||||
use App\Models\Location;
|
||||
use App\Models\Manufacturer;
|
||||
|
@ -125,11 +126,12 @@ class AccessoryFactory extends Factory
|
|||
})->afterCreating(function ($accessory) {
|
||||
$user = User::factory()->create();
|
||||
|
||||
$accessory->users()->attach($accessory->id, [
|
||||
$accessory->checkouts()->create([
|
||||
'accessory_id' => $accessory->id,
|
||||
'created_at' => now(),
|
||||
'created_at' => Carbon::now(),
|
||||
'user_id' => $user->id,
|
||||
'assigned_to' => $user->id,
|
||||
'assigned_type' => User::class,
|
||||
'note' => '',
|
||||
]);
|
||||
});
|
||||
|
@ -145,11 +147,12 @@ class AccessoryFactory extends Factory
|
|||
public function checkedOutToUser(User $user = null)
|
||||
{
|
||||
return $this->afterCreating(function (Accessory $accessory) use ($user) {
|
||||
$accessory->users()->attach($accessory->id, [
|
||||
$accessory->checkouts()->create([
|
||||
'accessory_id' => $accessory->id,
|
||||
'created_at' => Carbon::now(),
|
||||
'user_id' => 1,
|
||||
'assigned_to' => $user->id ?? User::factory()->create()->id,
|
||||
'assigned_type' => User::class,
|
||||
]);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -2,10 +2,15 @@
|
|||
|
||||
namespace Database\Factories;
|
||||
|
||||
use App\Models\Accessory;
|
||||
use App\Models\Asset;
|
||||
use App\Models\Category;
|
||||
use App\Models\Company;
|
||||
use App\Models\Component;
|
||||
use App\Models\Consumable;
|
||||
use App\Models\Location;
|
||||
use App\Models\User;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
use App\Models\Supplier;
|
||||
|
||||
|
@ -97,5 +102,16 @@ class ComponentFactory extends Factory
|
|||
});
|
||||
}
|
||||
|
||||
public function checkedOutToAsset(Asset $asset = null)
|
||||
{
|
||||
return $this->afterCreating(function (Component $component) use ($asset) {
|
||||
$component->assets()->attach($component->id, [
|
||||
'component_id' => $component->id,
|
||||
'created_at' => Carbon::now(),
|
||||
'user_id' => 1,
|
||||
'asset_id' => $asset->id ?? Asset::factory()->create()->id,
|
||||
]);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use App\Models\Setting;
|
||||
use App\Models\User;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
if (Schema::hasTable('accessories_users')) {
|
||||
Schema::rename('accessories_users', 'accessories_checkout');
|
||||
|
||||
Schema::table('accessories_checkout', function (Blueprint $table) {
|
||||
if (!Schema::hasColumn('accessories_checkout', 'assigned_type')) {
|
||||
$table->string('assigned_type')->nullable();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
DB::update('update '.DB::getTablePrefix().'accessories_checkout set assigned_type = \'App\\\\Models\\\\User\' where assigned_type is null', []);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
if (Schema::hasTable('accessories_checkout')) {
|
||||
Schema::table('accessories_checkout', function (Blueprint $table) {
|
||||
$table->dropColumn('assigned_type');
|
||||
});
|
||||
|
||||
Schema::rename('accessories_checkout', 'accessories_users');
|
||||
}
|
||||
}
|
||||
};
|
|
@ -16,7 +16,7 @@ class AccessorySeeder extends Seeder
|
|||
public function run()
|
||||
{
|
||||
Accessory::truncate();
|
||||
DB::table('accessories_users')->truncate();
|
||||
DB::table('accessories_checkout')->truncate();
|
||||
|
||||
if (! Location::count()) {
|
||||
$this->call(LocationSeeder::class);
|
||||
|
|
|
@ -714,6 +714,11 @@ th.css-location > .th-inner::before {
|
|||
margin-top:50px
|
||||
}
|
||||
}
|
||||
@media screen and (max-width: 1318px) and (min-width: 1200px){
|
||||
.box{
|
||||
height:170px;
|
||||
}
|
||||
}
|
||||
|
||||
.ellipsis {
|
||||
overflow: hidden;
|
||||
|
|
|
@ -14,6 +14,9 @@ return [
|
|||
'restore_warning' => 'Yes, restore it. I acknowledge that this will overwrite any existing data currently in the database. This will also log out all of your existing users (including you).',
|
||||
'restore_confirm' => 'Are you sure you wish to restore your database from :filename?'
|
||||
],
|
||||
'restore' => [
|
||||
'success' => 'Your system backup has been restored. Please login again.'
|
||||
],
|
||||
'purge' => [
|
||||
'error' => 'An error has occurred while purging. ',
|
||||
'validation_failed' => 'Your purge confirmation is incorrect. Please type the word "DELETE" in the confirmation box.',
|
||||
|
|
|
@ -188,6 +188,8 @@ return [
|
|||
'hashed_pass' => 'Your current password is incorrect',
|
||||
'dumbpwd' => 'That password is too common.',
|
||||
'statuslabel_type' => 'You must select a valid status label type',
|
||||
'custom_field_not_found' => 'This field does not seem to exist, please double check your custom field names.',
|
||||
'custom_field_not_found_on_model' => 'This field seems to exist, but is not available on this Asset Model\'s fieldset.',
|
||||
|
||||
// date_format validation with slightly less stupid messages. It duplicates a lot, but it gets the job done :(
|
||||
// We use this because the default error message for date_format is reflects php Y-m-d, which non-PHP
|
||||
|
|
|
@ -556,7 +556,7 @@ return [
|
|||
'something_went_wrong' => 'Something went wrong with your request.',
|
||||
'close' => 'Close',
|
||||
'expires' => 'Expires',
|
||||
'map_fields'=> 'Map :item_type Field',
|
||||
'map_fields'=> 'Map :item_type Fields',
|
||||
'remaining_var' => ':count Remaining',
|
||||
|
||||
];
|
||||
|
|
|
@ -71,11 +71,15 @@
|
|||
</div>
|
||||
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<a class="btn btn-link" href="{{ URL::previous() }}">{{ trans('button.cancel') }}</a>
|
||||
<button type="submit" class="btn btn-primary pull-right"><i class="fas fa-check icon-white" aria-hidden="true"></i>
|
||||
{{ trans('general.checkin') }}</button>
|
||||
</div>
|
||||
<x-redirect_submit_options
|
||||
index_route="accessories.index"
|
||||
:button_label="trans('general.checkin')"
|
||||
:options="[
|
||||
'index' => trans('admin/hardware/form.redirect_to_all', ['type' => trans('general.accessories')]),
|
||||
'item' => trans('admin/hardware/form.redirect_to_type', ['type' => trans('general.accessory')]),
|
||||
|
||||
]"
|
||||
/>
|
||||
|
||||
|
||||
</div> <!-- .box.box-default -->
|
||||
|
|
|
@ -66,7 +66,14 @@
|
|||
</div>
|
||||
<!-- User -->
|
||||
|
||||
@include ('partials.forms.edit.user-select', ['translated_name' => trans('general.select_user'), 'fieldname' => 'assigned_to', 'required'=> 'true'])
|
||||
@include ('partials.forms.checkout-selector', ['user_select' => 'true','asset_select' => 'true', 'location_select' => 'true'])
|
||||
|
||||
@include ('partials.forms.edit.user-select', ['translated_name' => trans('general.select_user'), 'fieldname' => 'assigned_user', 'required'=> 'true'])
|
||||
|
||||
<!-- We have to pass unselect here so that we don't default to the asset that's being checked out. We want that asset to be pre-selected everywhere else. -->
|
||||
@include ('partials.forms.edit.asset-select', ['translated_name' => trans('general.asset'), 'fieldname' => 'assigned_asset', 'unselect' => 'true', 'style' => 'display:none;', 'required'=>'true'])
|
||||
|
||||
@include ('partials.forms.edit.location-select', ['translated_name' => trans('general.location'), 'fieldname' => 'assigned_location', 'style' => 'display:none;', 'required'=>'true'])
|
||||
|
||||
<!-- Checkout QTY -->
|
||||
<div class="form-group {{ $errors->has('checkout_qty') ? 'error' : '' }} ">
|
||||
|
@ -114,10 +121,16 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<a class="btn btn-link" href="{{ URL::previous() }}">{{ trans('button.cancel') }}</a>
|
||||
<button type="submit" id="submit_button" class="btn btn-primary pull-right"><i class="fas fa-check icon-white" aria-hidden="true"></i> {{ trans('general.checkout') }}</button>
|
||||
</div>
|
||||
<x-redirect_submit_options
|
||||
index_route="accessories.index"
|
||||
:button_label="trans('general.checkout')"
|
||||
:options="[
|
||||
'index' => trans('admin/hardware/form.redirect_to_all', ['type' => trans('general.accessories')]),
|
||||
'item' => trans('admin/hardware/form.redirect_to_type', ['type' => trans('general.accessory')]),
|
||||
'target' => trans('admin/hardware/form.redirect_to_checked_out_to'),
|
||||
|
||||
]"
|
||||
/>
|
||||
</div> <!-- .box.box-default -->
|
||||
</form>
|
||||
</div> <!-- .col-md-9-->
|
||||
|
|
|
@ -4,6 +4,11 @@
|
|||
'helpPosition' => 'right',
|
||||
'helpText' => trans('help.accessories'),
|
||||
'formAction' => (isset($item->id)) ? route('accessories.update', ['accessory' => $item->id]) : route('accessories.store'),
|
||||
'index_route' => 'accessories.index',
|
||||
'options' => [
|
||||
'index' => trans('admin/hardware/form.redirect_to_all', ['type' => 'accessories']),
|
||||
'item' => trans('admin/hardware/form.redirect_to_type', ['type' => trans('general.accessory')]),
|
||||
]
|
||||
])
|
||||
|
||||
{{-- Page content --}}
|
||||
|
|
|
@ -68,9 +68,9 @@
|
|||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<table
|
||||
data-cookie-id-table="usersTable"
|
||||
data-cookie-id-table="checkoutsTable"
|
||||
data-pagination="true"
|
||||
data-id-table="usersTable"
|
||||
data-id-table="checkoutsTable"
|
||||
data-search="true"
|
||||
data-side-pagination="server"
|
||||
data-show-columns="true"
|
||||
|
@ -78,16 +78,16 @@
|
|||
data-show-export="true"
|
||||
data-show-refresh="true"
|
||||
data-sort-order="asc"
|
||||
id="usersTable"
|
||||
id="checkoutsTable"
|
||||
class="table table-striped snipe-table"
|
||||
data-url="{{ route('api.accessories.checkedout', $accessory->id) }}"
|
||||
data-export-options='{
|
||||
"fileName": "export-accessories-{{ str_slug($accessory->name) }}-users-{{ date('Y-m-d') }}",
|
||||
"fileName": "export-accessories-{{ str_slug($accessory->name) }}-checkouts-{{ date('Y-m-d') }}",
|
||||
"ignoreColumn": ["actions","image","change","checkbox","checkincheckout","icon"]
|
||||
}'>
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-searchable="false" data-formatter="usersLinkFormatter" data-sortable="false" data-field="name">{{ trans('general.user') }}</th>
|
||||
<th data-searchable="false" data-formatter="polymorphicItemFormatter" data-sortable="false" data-field="assigned_to">{{ trans('general.checked_out_to') }}</th>
|
||||
<th data-searchable="false" data-sortable="false" data-field="checkout_notes">{{ trans('general.notes') }}</th>
|
||||
<th data-searchable="false" data-formatter="dateDisplayFormatter" data-sortable="false" data-field="last_checkout">{{ trans('admin/hardware/table.checkout_date') }}</th>
|
||||
<th data-searchable="false" data-sortable="false" data-field="actions" data-formatter="accessoriesInOutFormatter">{{ trans('table.actions') }}</th>
|
||||
|
@ -314,7 +314,7 @@
|
|||
<strong>{{ trans('general.checked_out') }}</strong>
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
{{ $accessory->users_count }}
|
||||
{{ $accessory->checkouts_count }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -337,7 +337,7 @@
|
|||
@endcan
|
||||
|
||||
@can('delete', $accessory)
|
||||
@if ($accessory->users_count == 0)
|
||||
@if ($accessory->checkouts_count == 0)
|
||||
<div class="text-center" style="padding-top:5px;">
|
||||
<button class="btn btn-block btn-danger delete-asset" style="padding-top:5px;" data-toggle="modal" data-title="{{ trans('general.delete') }}" data-content="{{ trans('general.delete_confirm_no_undo', ['item' => $accessory->name]) }}" data-target="#dataConfirmModal">
|
||||
{{ trans('general.delete') }}
|
||||
|
|
3
resources/views/blade/example.blade.php
Normal file
3
resources/views/blade/example.blade.php
Normal file
|
@ -0,0 +1,3 @@
|
|||
<p>
|
||||
Hi.
|
||||
</p>
|
38
resources/views/blade/redirect_submit_options.blade.php
Normal file
38
resources/views/blade/redirect_submit_options.blade.php
Normal file
|
@ -0,0 +1,38 @@
|
|||
<!-- begin redirect submit options -->
|
||||
@props([
|
||||
'index_route',
|
||||
'button_label',
|
||||
'disabled_select' => false,
|
||||
'options' => [],
|
||||
])
|
||||
|
||||
<div class="box-footer">
|
||||
<div class="row">
|
||||
|
||||
<div class="col-md-3">
|
||||
<a class="btn btn-link" href="{{ $index_route ? route($index_route) : url()->previous() }}">{{ trans('button.cancel') }}</a>
|
||||
</div>
|
||||
|
||||
<div class="col-md-9 text-right">
|
||||
<div class="btn-group text-left">
|
||||
|
||||
@if (($options) && (count($options) > 0))
|
||||
<select class="redirect-options form-control select2" data-minimum-results-for-search="Infinity" name="redirect_option" style="min-width: 250px"{{ ($disabled_select ? ' disabled' : '') }}>
|
||||
@foreach ($options as $key => $value)
|
||||
<option value="{{ $key }}"{{ Session::get('redirect_option') == $key ? ' selected' : ''}}>
|
||||
{{ $value }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
@endif
|
||||
|
||||
<button type="submit" class="btn btn-primary pull-right{{ ($disabled_select ? ' disabled' : '') }}" style="margin-left:5px; border-radius: 3px;"{!! ($disabled_select ? ' data-tooltip="true" title="'.trans('admin/hardware/general.edit').'" disabled' : '') !!}>
|
||||
<i class="fas fa-check icon-white" aria-hidden="true"></i>
|
||||
{{ $button_label }}
|
||||
</button>
|
||||
|
||||
</div><!-- /.btn-group -->
|
||||
</div><!-- /.col-md-9 -->
|
||||
</div><!-- /.row -->
|
||||
</div> <!-- /.box-footer -->
|
||||
<!-- end redirect submit options -->
|
|
@ -56,10 +56,14 @@
|
|||
{!! $errors->first('note', '<span class="alert-msg" aria-hidden="true"><i class="fas fa-times" aria-hidden="true"></i> :message</span>') !!}
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<a class="btn btn-link" href="{{ route('components.index') }}">{{ trans('button.cancel') }}</a>
|
||||
<button type="submit" class="btn btn-primary pull-right"><i class="fas fa-check icon-white" aria-hidden="true"></i> {{ trans('general.checkin') }}</button>
|
||||
</div>
|
||||
<x-redirect_submit_options
|
||||
index_route="components.index"
|
||||
:button_label="trans('general.checkin')"
|
||||
:options="[
|
||||
'index' => trans('admin/hardware/form.redirect_to_all', ['type' => trans('general.components')]),
|
||||
'item' => trans('admin/hardware/form.redirect_to_type', ['type' => trans('general.component')]),
|
||||
]"
|
||||
/>
|
||||
</div> <!-- /.box-->
|
||||
</form>
|
||||
</div> <!-- /.col-md-7-->
|
||||
|
|
|
@ -54,10 +54,16 @@
|
|||
|
||||
|
||||
</div> <!-- .BOX-BODY-->
|
||||
<div class="box-footer">
|
||||
<a class="btn btn-link" href="{{ URL::previous() }}">{{ trans('button.cancel') }}</a>
|
||||
<button type="submit" id="submit_button" class="btn btn-primary pull-right"><i class="fas fa-check icon-white" aria-hidden="true"></i> {{ trans('general.checkout') }}</button>
|
||||
</div>
|
||||
<x-redirect_submit_options
|
||||
index_route="components.index"
|
||||
:button_label="trans('general.checkout')"
|
||||
:options="[
|
||||
'index' => trans('admin/hardware/form.redirect_to_all', ['type' => trans('general.components')]),
|
||||
'item' => trans('admin/hardware/form.redirect_to_type', ['type' => trans('general.component')]),
|
||||
'target' => trans('admin/hardware/form.redirect_to_checked_out_to'),
|
||||
|
||||
]"
|
||||
/>
|
||||
</div> <!-- .box-default-->
|
||||
</form>
|
||||
</div> <!-- .col-md-9-->
|
||||
|
|
|
@ -4,6 +4,11 @@
|
|||
'helpPosition' => 'right',
|
||||
'helpText' => trans('help.components'),
|
||||
'formAction' => (isset($item->id)) ? route('components.update', ['component' => $item->id]) : route('components.store'),
|
||||
'index_route' => 'components.index',
|
||||
'options' => [
|
||||
'index' => trans('admin/hardware/form.redirect_to_all', ['type' => 'components']),
|
||||
'item' => trans('admin/hardware/form.redirect_to_type', ['type' => trans('general.component')]),
|
||||
]
|
||||
|
||||
])
|
||||
|
||||
|
|
|
@ -106,10 +106,14 @@
|
|||
</div>
|
||||
</div>
|
||||
</div> <!-- .box-body -->
|
||||
<div class="box-footer">
|
||||
<a class="btn btn-link" href="{{ route('consumables.show', ['consumable'=> $consumable->id]) }}">{{ trans('button.cancel') }}</a>
|
||||
<button type="submit" id="submit_button" class="btn btn-primary pull-right"><i class="fas fa-check icon-white" aria-hidden="true"></i> {{ trans('general.checkout') }}</button>
|
||||
</div>
|
||||
<x-redirect_submit_options
|
||||
index_route="consumables.index"
|
||||
:button_label="trans('general.checkout')"
|
||||
:options="[
|
||||
'index' => trans('admin/hardware/form.redirect_to_all', ['type' => trans('general.consumables')]),
|
||||
'item' => trans('admin/hardware/form.redirect_to_type', ['type' => trans('general.consumable')]),
|
||||
'target' => trans('admin/hardware/form.redirect_to_checked_out_to'),
|
||||
]"/>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
|
|
@ -4,6 +4,11 @@
|
|||
'helpPosition' => 'right',
|
||||
'helpText' => trans('help.consumables'),
|
||||
'formAction' => (isset($item->id)) ? route('consumables.update', ['consumable' => $item->id]) : route('consumables.store'),
|
||||
'index_route' => 'consumables.index',
|
||||
'options' => [
|
||||
'index' => trans('admin/hardware/form.redirect_to_all', ['type' => 'consumables']),
|
||||
'item' => trans('admin/hardware/form.redirect_to_type', ['type' => trans('general.consumable')]),
|
||||
]
|
||||
])
|
||||
{{-- Page content --}}
|
||||
@section('inputFields')
|
||||
|
|
|
@ -2,132 +2,144 @@
|
|||
|
||||
{{-- Page title --}}
|
||||
@section('title')
|
||||
{{ trans('admin/hardware/general.checkin') }}
|
||||
@parent
|
||||
{{ trans('admin/hardware/general.checkin') }}
|
||||
@parent
|
||||
@stop
|
||||
|
||||
{{-- Page content --}}
|
||||
@section('content')
|
||||
<style>
|
||||
<style>
|
||||
|
||||
.input-group {
|
||||
padding-left: 0px !important;
|
||||
}
|
||||
</style>
|
||||
.input-group {
|
||||
padding-left: 0px !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
<div class="row"><!-- .row -->
|
||||
<!-- left column -->
|
||||
<div class="col-md-7 col-sm-11 col-xs-12 col-md-offset-2">
|
||||
<div class="box box-default"><!-- .box-default -->
|
||||
<div class="box-header with-border"><!-- .box-header -->
|
||||
<h2 class="box-title">
|
||||
{{ trans('admin/hardware/form.tag') }}
|
||||
{{ $asset->asset_tag }}
|
||||
</h2>
|
||||
</div><!-- /.box-header -->
|
||||
<div class="row"><!-- .row -->
|
||||
<!-- left column -->
|
||||
<div class="col-md-7 col-sm-11 col-xs-12 col-md-offset-2">
|
||||
<div class="box box-default"><!-- .box-default -->
|
||||
<div class="box-header with-border"><!-- .box-header -->
|
||||
<h2 class="box-title">
|
||||
{{ trans('admin/hardware/form.tag') }}
|
||||
{{ $asset->asset_tag }}
|
||||
</h2>
|
||||
</div><!-- /.box-header -->
|
||||
|
||||
<div class="box-body"><!-- .box-body -->
|
||||
<div class="col-md-12"><!-- .col-md-12 -->
|
||||
<div class="box-body"><!-- .box-body -->
|
||||
<div class="col-md-12"><!-- .col-md-12 -->
|
||||
|
||||
@if ($backto == 'user')
|
||||
<form class="form-horizontal" method="post" action="{{ route('hardware.checkin.store', array('assetId'=> $asset->id, 'backto'=>'user')) }}" autocomplete="off">
|
||||
@else
|
||||
<form class="form-horizontal" method="post" action="{{ route('hardware.checkin.store', array('assetId'=> $asset->id)) }}" autocomplete="off">
|
||||
@endif
|
||||
{{csrf_field()}}
|
||||
@if ($backto == 'user')
|
||||
<form class="form-horizontal" method="post"
|
||||
action="{{ route('hardware.checkin.store', array('assetId'=> $asset->id, 'backto'=>'user')) }}"
|
||||
autocomplete="off">
|
||||
@else
|
||||
<form class="form-horizontal" method="post"
|
||||
action="{{ route('hardware.checkin.store', array('assetId'=> $asset->id)) }}"
|
||||
autocomplete="off">
|
||||
@endif
|
||||
{{csrf_field()}}
|
||||
|
||||
<!-- AssetModel name -->
|
||||
<div class="form-group">
|
||||
<label for="model" class="col-sm-3 control-label">
|
||||
{{ trans('admin/hardware/form.model') }}
|
||||
</label>
|
||||
<div class="col-md-8">
|
||||
<!-- AssetModel name -->
|
||||
<div class="form-group">
|
||||
<label for="model" class="col-sm-3 control-label">
|
||||
{{ trans('admin/hardware/form.model') }}
|
||||
</label>
|
||||
<div class="col-md-8">
|
||||
|
||||
<p class="form-control-static">
|
||||
@if (($asset->model) && ($asset->model->name))
|
||||
{{ $asset->model->name }}
|
||||
@else
|
||||
<span class="text-danger text-bold">
|
||||
<p class="form-control-static">
|
||||
@if (($asset->model) && ($asset->model->name))
|
||||
{{ $asset->model->name }}
|
||||
@else
|
||||
<span class="text-danger text-bold">
|
||||
<i class="fas fa-exclamation-triangle" aria-hidden="true"></i>
|
||||
{{ trans('admin/hardware/general.model_invalid')}}
|
||||
</span>
|
||||
{{ trans('admin/hardware/general.model_invalid_fix')}}
|
||||
<a href="{{ route('hardware.edit', $asset->id) }}">
|
||||
<strong>{{ trans('admin/hardware/general.edit') }}</strong>
|
||||
</a>
|
||||
@endif
|
||||
</p>
|
||||
{{ trans('admin/hardware/general.model_invalid_fix')}}
|
||||
<a href="{{ route('hardware.edit', $asset->id) }}">
|
||||
<strong>{{ trans('admin/hardware/general.edit') }}</strong>
|
||||
</a>
|
||||
@endif
|
||||
</p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Asset Name -->
|
||||
<div class="form-group {{ $errors->has('name') ? 'error' : '' }}">
|
||||
<label for="name" class="col-sm-3 control-label">
|
||||
{{ trans('general.name') }}
|
||||
</label>
|
||||
<div class="col-md-8">
|
||||
<input class="form-control" type="text" name="name" aria-label="name" id="name" value="{{ old('name', $asset->name) }}"/>
|
||||
{!! $errors->first('name', '<span class="alert-msg" aria-hidden="true"><i class="fas fa-times" aria-hidden="true"></i> :message</span>') !!}
|
||||
</div>
|
||||
</div>
|
||||
<!-- Asset Name -->
|
||||
<div class="form-group {{ $errors->has('name') ? 'error' : '' }}">
|
||||
<label for="name" class="col-sm-3 control-label">
|
||||
{{ trans('general.name') }}
|
||||
</label>
|
||||
<div class="col-md-8">
|
||||
<input class="form-control" type="text" name="name" aria-label="name"
|
||||
id="name" value="{{ old('name', $asset->name) }}"/>
|
||||
{!! $errors->first('name', '<span class="alert-msg" aria-hidden="true"><i class="fas fa-times" aria-hidden="true"></i> :message</span>') !!}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Status -->
|
||||
<div class="form-group {{ $errors->has('status_id') ? 'error' : '' }}">
|
||||
<label for="status_id" class="col-sm-3 control-label">
|
||||
{{ trans('admin/hardware/form.status') }}
|
||||
</label>
|
||||
<div class="col-md-8 required">
|
||||
{{ Form::select('status_id', $statusLabel_list, '', array('class'=>'select2', 'style'=>'width:100%','id' =>'modal-statuslabel_types', 'aria-label'=>'status_id')) }}
|
||||
{!! $errors->first('status_id', '<span class="alert-msg" aria-hidden="true"><i class="fas fa-times" aria-hidden="true"></i> :message</span>') !!}
|
||||
</div>
|
||||
</div>
|
||||
<!-- Status -->
|
||||
<div class="form-group {{ $errors->has('status_id') ? 'error' : '' }}">
|
||||
<label for="status_id" class="col-sm-3 control-label">
|
||||
{{ trans('admin/hardware/form.status') }}
|
||||
</label>
|
||||
<div class="col-md-8 required">
|
||||
{{ Form::select('status_id', $statusLabel_list, '', array('class'=>'select2', 'style'=>'width:100%','id' =>'modal-statuslabel_types', 'aria-label'=>'status_id')) }}
|
||||
{!! $errors->first('status_id', '<span class="alert-msg" aria-hidden="true"><i class="fas fa-times" aria-hidden="true"></i> :message</span>') !!}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@include ('partials.forms.edit.location-select', ['translated_name' => trans('general.location'), 'fieldname' => 'location_id', 'help_text' => ($asset->defaultLoc) ? trans('general.checkin_to_diff_location', ['default_location' => $asset->defaultLoc->name]) : null, 'hide_location_radio' => true])
|
||||
@include ('partials.forms.edit.location-select', ['translated_name' => trans('general.location'), 'fieldname' => 'location_id', 'help_text' => ($asset->defaultLoc) ? trans('general.checkin_to_diff_location', ['default_location' => $asset->defaultLoc->name]) : null, 'hide_location_radio' => true])
|
||||
|
||||
<!-- Checkout/Checkin Date -->
|
||||
<div class="form-group{{ $errors->has('checkin_at') ? ' has-error' : '' }}">
|
||||
<label for="checkin_at" class="col-sm-3 control-label">
|
||||
{{ trans('admin/hardware/form.checkin_date') }}
|
||||
</label>
|
||||
<!-- Checkout/Checkin Date -->
|
||||
<div class="form-group{{ $errors->has('checkin_at') ? ' has-error' : '' }}">
|
||||
<label for="checkin_at" class="col-sm-3 control-label">
|
||||
{{ trans('admin/hardware/form.checkin_date') }}
|
||||
</label>
|
||||
|
||||
<div class="col-md-8">
|
||||
<div class="input-group col-md-5 required">
|
||||
<div class="input-group date" data-provide="datepicker" data-date-format="yyyy-mm-dd" data-autoclose="true">
|
||||
<input type="text" class="form-control" placeholder="{{ trans('general.select_date') }}" name="checkin_at" id="checkin_at" value="{{ old('checkin_at', date('Y-m-d')) }}">
|
||||
<span class="input-group-addon"><i class="fas fa-calendar" aria-hidden="true"></i></span>
|
||||
</div>
|
||||
{!! $errors->first('checkin_at', '<span class="alert-msg" aria-hidden="true"><i class="fas fa-times" aria-hidden="true"></i> :message</span>') !!}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<div class="input-group col-md-5 required">
|
||||
<div class="input-group date" data-provide="datepicker"
|
||||
data-date-format="yyyy-mm-dd" data-autoclose="true">
|
||||
<input type="text" class="form-control"
|
||||
placeholder="{{ trans('general.select_date') }}"
|
||||
name="checkin_at" id="checkin_at"
|
||||
value="{{ old('checkin_at', date('Y-m-d')) }}">
|
||||
<span class="input-group-addon"><i class="fas fa-calendar"
|
||||
aria-hidden="true"></i></span>
|
||||
</div>
|
||||
{!! $errors->first('checkin_at', '<span class="alert-msg" aria-hidden="true"><i class="fas fa-times" aria-hidden="true"></i> :message</span>') !!}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Note -->
|
||||
<div class="form-group {{ $errors->has('note') ? 'error' : '' }}">
|
||||
<label for="note" class="col-sm-3 control-label">
|
||||
{{ trans('general.notes') }}
|
||||
</label>
|
||||
<div class="col-md-8">
|
||||
<textarea class="col-md-6 form-control" id="note" name="note">{{ old('note', $asset->note) }}</textarea>
|
||||
{!! $errors->first('note', '<span class="alert-msg" aria-hidden="true"><i class="fas fa-times" aria-hidden="true"></i> :message</span>') !!}
|
||||
</div>
|
||||
</div>
|
||||
<!-- Note -->
|
||||
<div class="form-group {{ $errors->has('note') ? 'error' : '' }}">
|
||||
<label for="note" class="col-sm-3 control-label">
|
||||
{{ trans('general.notes') }}
|
||||
</label>
|
||||
<div class="col-md-8">
|
||||
<textarea class="col-md-6 form-control" id="note"
|
||||
name="note">{{ old('note', $asset->note) }}</textarea>
|
||||
{!! $errors->first('note', '<span class="alert-msg" aria-hidden="true"><i class="fas fa-times" aria-hidden="true"></i> :message</span>') !!}
|
||||
</div>
|
||||
</div>
|
||||
</div> <!--/.box-body-->
|
||||
</div> <!--/.box-body-->
|
||||
|
||||
@include ('partials.forms.redirect_submit_options',
|
||||
[
|
||||
'route' => 'hardware.index',
|
||||
'table_name' => $table_name,
|
||||
'type'=> ($asset->model ? $asset->model->name : trans('general.asset_model')),
|
||||
'checkin' => true
|
||||
])
|
||||
</form>
|
||||
<x-redirect_submit_options
|
||||
index_route="hardware.index"
|
||||
:button_label="trans('general.checkin')"
|
||||
:disabled_select="!$asset->model"
|
||||
:options="[
|
||||
'index' => trans('admin/hardware/form.redirect_to_all', ['type' => 'assets']),
|
||||
'item' => trans('admin/hardware/form.redirect_to_type', ['type' => trans('general.asset')]),
|
||||
]"
|
||||
/>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@stop
|
|
@ -25,7 +25,7 @@
|
|||
<h2 class="box-title"> {{ trans('admin/hardware/form.tag') }} {{ $asset->asset_tag }}</h2>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
{{csrf_field()}}
|
||||
{{csrf_field()}}
|
||||
@if ($asset->company && $asset->company->name)
|
||||
<div class="form-group">
|
||||
<label for="company" class="col-md-3 control-label">
|
||||
|
@ -70,7 +70,8 @@
|
|||
</label>
|
||||
|
||||
<div class="col-md-8">
|
||||
<input class="form-control" type="text" name="name" id="name" value="{{ old('name', $asset->name) }}" tabindex="1">
|
||||
<input class="form-control" type="text" name="name" id="name"
|
||||
value="{{ old('name', $asset->name) }}" tabindex="1">
|
||||
{!! $errors->first('name', '<span class="alert-msg" aria-hidden="true"><i class="fas fa-times" aria-hidden="true"></i> :message</span>') !!}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -86,26 +87,30 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
@include ('partials.forms.checkout-selector', ['user_select' => 'true','asset_select' => 'true', 'location_select' => 'true'])
|
||||
@include ('partials.forms.checkout-selector', ['user_select' => 'true','asset_select' => 'true', 'location_select' => 'true'])
|
||||
|
||||
@include ('partials.forms.edit.user-select', ['translated_name' => trans('general.user'), 'fieldname' => 'assigned_user', 'required'=>'true'])
|
||||
@include ('partials.forms.edit.user-select', ['translated_name' => trans('general.user'), 'fieldname' => 'assigned_user', 'required'=>'true'])
|
||||
|
||||
<!-- We have to pass unselect here so that we don't default to the asset that's being checked out. We want that asset to be pre-selected everywhere else. -->
|
||||
@include ('partials.forms.edit.asset-select', ['translated_name' => trans('general.asset'), 'fieldname' => 'assigned_asset', 'unselect' => 'true', 'style' => 'display:none;', 'required'=>'true'])
|
||||
<!-- We have to pass unselect here so that we don't default to the asset that's being checked out. We want that asset to be pre-selected everywhere else. -->
|
||||
@include ('partials.forms.edit.asset-select', ['translated_name' => trans('general.asset'), 'fieldname' => 'assigned_asset', 'unselect' => 'true', 'style' => 'display:none;', 'required'=>'true'])
|
||||
|
||||
@include ('partials.forms.edit.location-select', ['translated_name' => trans('general.location'), 'fieldname' => 'assigned_location', 'style' => 'display:none;', 'required'=>'true'])
|
||||
@include ('partials.forms.edit.location-select', ['translated_name' => trans('general.location'), 'fieldname' => 'assigned_location', 'style' => 'display:none;', 'required'=>'true'])
|
||||
|
||||
|
||||
|
||||
<!-- Checkout/Checkin Date -->
|
||||
<!-- Checkout/Checkin Date -->
|
||||
<div class="form-group {{ $errors->has('checkout_at') ? 'error' : '' }}">
|
||||
<label for="checkout_at" class="col-md-3 control-label">
|
||||
{{ trans('admin/hardware/form.checkout_date') }}
|
||||
</label>
|
||||
<div class="col-md-8">
|
||||
<div class="input-group date col-md-7" data-provide="datepicker" data-date-format="yyyy-mm-dd" data-date-end-date="0d" data-date-clear-btn="true">
|
||||
<input type="text" class="form-control" placeholder="{{ trans('general.select_date') }}" name="checkout_at" id="checkout_at" value="{{ old('checkout_at', date('Y-m-d')) }}">
|
||||
<span class="input-group-addon"><i class="fas fa-calendar" aria-hidden="true"></i></span>
|
||||
<div class="input-group date col-md-7" data-provide="datepicker"
|
||||
data-date-format="yyyy-mm-dd" data-date-end-date="0d" data-date-clear-btn="true">
|
||||
<input type="text" class="form-control"
|
||||
placeholder="{{ trans('general.select_date') }}" name="checkout_at"
|
||||
id="checkout_at" value="{{ old('checkout_at', date('Y-m-d')) }}">
|
||||
<span class="input-group-addon"><i class="fas fa-calendar"
|
||||
aria-hidden="true"></i></span>
|
||||
</div>
|
||||
{!! $errors->first('checkout_at', '<span class="alert-msg" aria-hidden="true"><i class="fas fa-times" aria-hidden="true"></i> :message</span>') !!}
|
||||
</div>
|
||||
|
@ -118,9 +123,13 @@
|
|||
</label>
|
||||
|
||||
<div class="col-md-8">
|
||||
<div class="input-group date col-md-7" data-provide="datepicker" data-date-format="yyyy-mm-dd" data-date-start-date="0d" data-date-clear-btn="true">
|
||||
<input type="text" class="form-control" placeholder="{{ trans('general.select_date') }}" name="expected_checkin" id="expected_checkin" value="{{ old('expected_checkin') }}">
|
||||
<span class="input-group-addon"><i class="fas fa-calendar" aria-hidden="true"></i></span>
|
||||
<div class="input-group date col-md-7" data-provide="datepicker"
|
||||
data-date-format="yyyy-mm-dd" data-date-start-date="0d" data-date-clear-btn="true">
|
||||
<input type="text" class="form-control"
|
||||
placeholder="{{ trans('general.select_date') }}" name="expected_checkin"
|
||||
id="expected_checkin" value="{{ old('expected_checkin') }}">
|
||||
<span class="input-group-addon"><i class="fas fa-calendar"
|
||||
aria-hidden="true"></i></span>
|
||||
</div>
|
||||
{!! $errors->first('expected_checkin', '<span class="alert-msg" aria-hidden="true"><i class="fas fa-times" aria-hidden="true"></i> :message</span>') !!}
|
||||
</div>
|
||||
|
@ -132,7 +141,8 @@
|
|||
{{ trans('general.notes') }}
|
||||
</label>
|
||||
<div class="col-md-8">
|
||||
<textarea class="col-md-6 form-control" id="note" name="note">{{ old('note', $asset->note) }}</textarea>
|
||||
<textarea class="col-md-6 form-control" id="note"
|
||||
name="note">{{ old('note', $asset->note) }}</textarea>
|
||||
{!! $errors->first('note', '<span class="alert-msg" aria-hidden="true"><i class="fas fa-times" aria-hidden="true"></i> :message</span>') !!}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -164,13 +174,19 @@
|
|||
@endif
|
||||
|
||||
</div> <!--/.box-body-->
|
||||
@include ('partials.forms.redirect_submit_options',
|
||||
[
|
||||
'route' => 'hardware.index',
|
||||
'table_name' => $table_name,
|
||||
'type'=> ($asset->model ? $asset->model->name : trans('general.asset_model')),
|
||||
'checkin' => false
|
||||
])
|
||||
|
||||
<x-redirect_submit_options
|
||||
index_route="hardware.index"
|
||||
:button_label="trans('general.checkout')"
|
||||
:disabled_select="!$asset->model"
|
||||
:options="[
|
||||
'index' => trans('admin/hardware/form.redirect_to_all', ['type' => 'assets']),
|
||||
'item' => trans('admin/hardware/form.redirect_to_type', ['type' => trans('general.asset')]),
|
||||
'target' => trans('admin/hardware/form.redirect_to_checked_out_to'),
|
||||
|
||||
]"
|
||||
/>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
</div> <!--/.col-md-7-->
|
||||
|
|
|
@ -6,6 +6,11 @@
|
|||
'helpText' => trans('help.assets'),
|
||||
'helpPosition' => 'right',
|
||||
'formAction' => ($item->id) ? route('hardware.update', ['hardware' => $item->id]) : route('hardware.store'),
|
||||
'index_route' => 'hardware.index',
|
||||
'options' => [
|
||||
'index' => trans('admin/hardware/form.redirect_to_all', ['type' => 'assets']),
|
||||
'item' => trans('admin/hardware/form.redirect_to_type', ['type' => trans('general.asset')]),
|
||||
]
|
||||
])
|
||||
|
||||
|
||||
|
@ -130,12 +135,10 @@
|
|||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- byod checkbox -->
|
||||
<div class="form-group">
|
||||
<div class="col-md-7 col-md-offset-3">
|
||||
<label for="byod" class="form-control">
|
||||
<label class="form-control">
|
||||
<input type="checkbox" value="1" name="byod" {{ (old('remote', $item->byod)) == '1' ? ' checked="checked"' : '' }} aria-label="byod">
|
||||
{{ trans('general.byod') }}
|
||||
|
||||
|
|
|
@ -73,6 +73,7 @@
|
|||
data-pagination="true"
|
||||
data-id-table="assetsListingTable"
|
||||
data-search="true"
|
||||
data-search-text="{{ e(Session::get('search')) }}"
|
||||
data-side-pagination="server"
|
||||
data-show-columns="true"
|
||||
data-show-export="true"
|
||||
|
|
|
@ -211,7 +211,7 @@
|
|||
<span class="tooltip-wrapper"{!! (!$asset->model ? ' data-tooltip="true" title="'.trans('admin/hardware/general.model_invalid_fix').'"' : '') !!}>
|
||||
<a href="{{ route('asset.audit.create', $asset->id) }}" class="btn btn-sm btn-primary btn-block hidden-print{{ (!$asset->model ? ' disabled' : '') }}">
|
||||
{{ trans('general.audit') }}
|
||||
</a>
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
@endcan
|
||||
|
@ -297,17 +297,40 @@
|
|||
@endif
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@endif
|
||||
<br><br>
|
||||
@if ($snipeSettings->qr_code=='1')
|
||||
<div class="col-md-12 text-center" style="padding-top: 15px;">
|
||||
<img src="{{ config('app.url') }}/hardware/{{ $asset->id }}/qr_code" class="img-thumbnail" style="height: 150px; width: 150px; margin-right: 10px;" alt="QR code for {{ $asset->getDisplayNameAttribute() }}">
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<br><br>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- End button column -->
|
||||
|
||||
<div class="col-md-9 col-xs-12 col-sm-pull-3">
|
||||
|
||||
<div class="row-new-striped">
|
||||
|
||||
@if ($asset->asset_tag)
|
||||
<div class="row">
|
||||
<div class="col-md-3">
|
||||
<strong>{{ trans('admin/hardware/form.tag') }}</strong>
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
<span class="js-copy">{{ $asset->asset_tag }}</span>
|
||||
|
||||
<i class="fa-regular fa-clipboard js-copy-link" data-clipboard-target=".js-copy" aria-hidden="true" data-tooltip="true" data-placement="top" title="{{ trans('general.copy_to_clipboard') }}">
|
||||
<span class="sr-only">{{ trans('general.copy_to_clipboard') }}</span>
|
||||
</i>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
|
||||
@if ($asset->deleted_at!='')
|
||||
<div class="row">
|
||||
|
|
|
@ -1136,8 +1136,5 @@ dir="{{ Helper::determineLanguageDirection() }}">
|
|||
</script>
|
||||
@endif
|
||||
|
||||
@include('partials.bpay')
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -66,7 +66,11 @@
|
|||
<!-- CSRF Token -->
|
||||
{{ csrf_field() }}
|
||||
@yield('inputFields')
|
||||
@include('partials.forms.edit.submit')
|
||||
<x-redirect_submit_options
|
||||
:index_route="$index_route ?? null"
|
||||
:button_label="trans('general.save')"
|
||||
:options="$options ?? []"
|
||||
/>
|
||||
</div>
|
||||
|
||||
</div> <!-- ./box-body -->
|
||||
|
|
|
@ -56,10 +56,14 @@
|
|||
{!! $errors->first('notes', '<span class="alert-msg" aria-hidden="true"><i class="fas fa-times" aria-hidden="true"></i> :message</span>') !!}
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<a class="btn btn-link" href="{{ route('licenses.index') }}">{{ trans('button.cancel') }}</a>
|
||||
<button type="submit" class="btn btn-primary pull-right"><i class="fas fa-check icon-white" aria-hidden="true"></i> {{ trans('general.checkin') }}</button>
|
||||
</div>
|
||||
<x-redirect_submit_options
|
||||
index_route="licenses.index"
|
||||
:button_label="trans('general.checkin')"
|
||||
:options="[
|
||||
'index' => trans('admin/hardware/form.redirect_to_all', ['type' => trans('general.licenses')]),
|
||||
'item' => trans('admin/hardware/form.redirect_to_type', ['type' => trans('general.license')]),
|
||||
]"
|
||||
/>
|
||||
</div> <!-- /.box-->
|
||||
</form>
|
||||
</div> <!-- /.col-md-7-->
|
||||
|
|
|
@ -105,10 +105,15 @@
|
|||
</div>
|
||||
@endif
|
||||
|
||||
<div class="box-footer">
|
||||
<a class="btn btn-link" href="{{ route('licenses.index') }}">{{ trans('button.cancel') }}</a>
|
||||
<button type="submit" class="btn btn-primary pull-right"><i class="fas fa-check icon-white" aria-hidden="true"></i> {{ trans('general.checkout') }}</button>
|
||||
</div>
|
||||
<x-redirect_submit_options
|
||||
index_route="licenses.index"
|
||||
:button_label="trans('general.checkout')"
|
||||
:options="[
|
||||
'index' => trans('admin/hardware/form.redirect_to_all', ['type' => trans('general.licenses')]),
|
||||
'item' => trans('admin/hardware/form.redirect_to_type', ['type' => trans('general.license')]),
|
||||
'target' => trans('admin/hardware/form.redirect_to_checked_out_to'),
|
||||
]"
|
||||
/>
|
||||
</div> <!-- /.box-->
|
||||
</form>
|
||||
</div> <!-- /.col-md-7-->
|
||||
|
|
|
@ -3,6 +3,11 @@
|
|||
'updateText' => trans('admin/licenses/form.update'),
|
||||
'topSubmit' => true,
|
||||
'formAction' => ($item->id) ? route('licenses.update', ['license' => $item->id]) : route('licenses.store'),
|
||||
'index_route' => 'licenses.index',
|
||||
'options' => [
|
||||
'index' => trans('admin/hardware/form.redirect_to_all', ['type' => 'licenses']),
|
||||
'item' => trans('admin/hardware/form.redirect_to_type', ['type' => trans('general.license')]),
|
||||
]
|
||||
])
|
||||
|
||||
{{-- Page content --}}
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
@can('admin')
|
||||
@if ((config('services.baremetrics.enabled')=='true') && (config('services.baremetrics.app_key')) && (config('services.baremetrics.stripe_id')))
|
||||
<script>
|
||||
!function(){if(window.barepay&&window.barepay.created)window.console&&console.error&&console.error("Barepay snippet included twice.");else{window.barepay={created:!0};var a=document.createElement("script");a.src="https://baremetrics-dunning.baremetrics.com/js/application.js",a.async=!0;var b=document.getElementsByTagName("script")[0];b.parentNode.insertBefore(a,b),
|
||||
|
||||
window.barepay.params = {
|
||||
access_token_id: "{{ config('services.baremetrics.app_key') }}", // Your Recover API public key
|
||||
customer_oid: "{{ config('services.baremetrics.stripe_id') }}" // Customer ID whose card you're looking to update
|
||||
}
|
||||
|
||||
}}();
|
||||
</script>
|
||||
@else
|
||||
@endif
|
||||
@endcan
|
|
@ -1,36 +0,0 @@
|
|||
<!-- begin redirect submit options -->
|
||||
|
||||
<div class="box-footer">
|
||||
<div class="row">
|
||||
|
||||
<div class="col-md-3">
|
||||
<a class="btn btn-link" href="{{ route($route) }}">{{ trans('button.cancel') }}</a>
|
||||
</div>
|
||||
|
||||
<div class="col-md-9 text-right">
|
||||
<div class="btn-group text-left">
|
||||
|
||||
<select class="redirect-options form-control select2" data-minimum-results-for-search="Infinity" name="redirect_option" style="min-width: 200px"{{ (!$asset->model ? ' disabled' : '') }}>
|
||||
|
||||
<option {{ (Session::get('redirect_option')=="0" || (Session::get('redirect_option')=="2" && $checkin)) ? 'selected' : '' }} value="0">
|
||||
{{ trans('admin/hardware/form.redirect_to_all', ['type' => $table_name]) }}
|
||||
</option>
|
||||
<option {{ Session::get('redirect_option')=="1" ? 'selected' : ''}} value="1">
|
||||
{{ trans('admin/hardware/form.redirect_to_type', ['type' => $type]) }}
|
||||
</option>
|
||||
<option {{ Session::get('redirect_option')=="2" && !$checkin ? 'selected' : ''}}{{ $checkin ? 'hidden disabled' : '' }} value="2" >
|
||||
{{ !$checkin ? trans('admin/hardware/form.redirect_to_checked_out_to') : '' }}
|
||||
</option>
|
||||
|
||||
</select>
|
||||
|
||||
<button type="submit" class="btn btn-primary pull-right{{ (!$asset->model ? ' disabled' : '') }}" style="margin-left:5px; border-radius: 3px;"{!! (!$asset->model ? ' data-tooltip="true" title="'.trans('admin/hardware/general.edit').'" disabled' : '') !!}>
|
||||
<i class="fas fa-check icon-white" aria-hidden="true"></i>
|
||||
{{ $checkin ? trans('general.checkin') : trans('general.checkout') }}
|
||||
</button>
|
||||
|
||||
</div><!-- /.btn-group -->
|
||||
</div><!-- /.col-md-9 -->
|
||||
</div><!-- /.row -->
|
||||
</div> <!-- /.box-footer -->
|
||||
<!-- end redirect submit options -->
|
|
@ -596,9 +596,14 @@
|
|||
</table>
|
||||
</div><!-- /.tab-pane -->
|
||||
</div><!-- /.tab-content -->
|
||||
<div class="box-footer text-right">
|
||||
<button type="submit" accesskey="s" class="btn btn-primary"><i class="fas fa-check icon-white" aria-hidden="true"></i> {{ trans('general.save') }}</button>
|
||||
</div>
|
||||
<x-redirect_submit_options
|
||||
index_route="users.index"
|
||||
:button_label="trans('general.save')"
|
||||
:options="[
|
||||
'index' => trans('admin/hardware/form.redirect_to_all', ['type' => 'users']),
|
||||
'item' => trans('admin/hardware/form.redirect_to_type', ['type' => trans('general.user')]),
|
||||
]"
|
||||
/>
|
||||
</div><!-- nav-tabs-custom -->
|
||||
</form>
|
||||
</div> <!--/col-md-8-->
|
||||
|
@ -673,7 +678,7 @@ $(document).ready(function() {
|
|||
'bind': 'click',
|
||||
'passwordElement': '#password',
|
||||
'displayElement': '#generated-password',
|
||||
'passwordLength': 16,
|
||||
'passwordLength': {{ ($settings->pwd_secure_min + 5) }},
|
||||
'uppercase': true,
|
||||
'lowercase': true,
|
||||
'numbers': true,
|
||||
|
|
|
@ -576,6 +576,7 @@ Route::group(['prefix' => 'v1', 'middleware' => ['api', 'throttle:api']], functi
|
|||
// this would probably keep working with the resource route group, but the general practice is for
|
||||
// the model name to be the parameter - and i think it's a good differentiation in the code while we convert the others.
|
||||
Route::patch('/hardware/{asset}', [Api\AssetsController::class, 'update'])->name('api.assets.update');
|
||||
Route::put('/hardware/{asset}', [Api\AssetsController::class, 'update'])->name('api.assets.put-update');
|
||||
|
||||
Route::resource('hardware',
|
||||
Api\AssetsController::class,
|
||||
|
@ -712,7 +713,7 @@ Route::group(['prefix' => 'v1', 'middleware' => ['api', 'throttle:api']], functi
|
|||
Route::get('{location}/assets',
|
||||
[
|
||||
Api\LocationsController::class,
|
||||
'getDataViewAssets'
|
||||
'assets'
|
||||
]
|
||||
)->name('api.locations.viewassets');
|
||||
|
||||
|
|
|
@ -3,17 +3,65 @@
|
|||
namespace Feature\Assets\Ui;
|
||||
|
||||
use App\Models\Asset;
|
||||
use App\Models\AssetModel;
|
||||
use App\Models\StatusLabel;
|
||||
use App\Models\User;
|
||||
use Tests\TestCase;
|
||||
|
||||
class EditAssetTest extends TestCase
|
||||
{
|
||||
|
||||
public function testPermissionRequiredToViewLicense()
|
||||
{
|
||||
$asset = Asset::factory()->create();
|
||||
$this->actingAs(User::factory()->create())
|
||||
->get(route('hardware.edit', $asset))
|
||||
->assertForbidden();
|
||||
}
|
||||
|
||||
public function testPageCanBeAccessed(): void
|
||||
{
|
||||
$asset = Asset::factory()->create();
|
||||
$user = User::factory()->editAssets()->create();
|
||||
$response = $this->actingAs($user)->get(route('hardware.edit', $asset->id));
|
||||
|
||||
$response->assertStatus(200);
|
||||
}
|
||||
|
||||
public function testAssetEditPostIsRedirectedIfRedirectSelectionIsIndex()
|
||||
{
|
||||
$asset = Asset::factory()->assignedToUser()->create();
|
||||
|
||||
$this->actingAs(User::factory()->viewAssets()->editAssets()->create())
|
||||
->from(route('hardware.edit', $asset))
|
||||
->put(route('hardware.update', $asset),
|
||||
[
|
||||
'redirect_option' => 'index',
|
||||
'name' => 'New name',
|
||||
'asset_tags' => 'New Asset Tag',
|
||||
'status_id' => StatusLabel::factory()->create()->id,
|
||||
'model_id' => AssetModel::factory()->create()->id,
|
||||
])
|
||||
->assertStatus(302)
|
||||
->assertRedirect(route('hardware.index'));
|
||||
$this->assertDatabaseHas('assets', ['asset_tag' => 'New Asset Tag']);
|
||||
}
|
||||
public function testAssetEditPostIsRedirectedIfRedirectSelectionIsItem()
|
||||
{
|
||||
$asset = Asset::factory()->create();
|
||||
|
||||
$this->actingAs(User::factory()->viewAssets()->editAssets()->create())
|
||||
->from(route('hardware.edit', $asset))
|
||||
->put(route('hardware.update', $asset), [
|
||||
'redirect_option' => 'item',
|
||||
'name' => 'New name',
|
||||
'asset_tags' => 'New Asset Tag',
|
||||
'status_id' => StatusLabel::factory()->create()->id,
|
||||
'model_id' => AssetModel::factory()->create()->id,
|
||||
])
|
||||
->assertStatus(302)
|
||||
->assertRedirect(route('hardware.show', ['hardware' => $asset->id]));
|
||||
|
||||
$this->assertDatabaseHas('assets', ['asset_tag' => 'New Asset Tag']);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ class AccessoryCheckinTest extends TestCase
|
|||
$accessory = Accessory::factory()->checkedOutToUser()->create();
|
||||
|
||||
$this->actingAs(User::factory()->create())
|
||||
->post(route('accessories.checkin.store', $accessory->users->first()->pivot->id))
|
||||
->post(route('accessories.checkin.store', $accessory->checkouts->first()->id))
|
||||
->assertForbidden();
|
||||
}
|
||||
|
||||
|
@ -28,12 +28,12 @@ class AccessoryCheckinTest extends TestCase
|
|||
$user = User::factory()->create();
|
||||
$accessory = Accessory::factory()->checkedOutToUser($user)->create();
|
||||
|
||||
$this->assertTrue($accessory->users->contains($user));
|
||||
$this->assertTrue($accessory->checkouts()->where('assigned_type', User::class)->where('assigned_to', $user->id)->count() > 0);
|
||||
|
||||
$this->actingAs(User::factory()->checkinAccessories()->create())
|
||||
->post(route('accessories.checkin.store', $accessory->users->first()->pivot->id));
|
||||
->post(route('accessories.checkin.store', $accessory->checkouts->first()->id));
|
||||
|
||||
$this->assertFalse($accessory->fresh()->users->contains($user));
|
||||
$this->assertFalse($accessory->fresh()->checkouts()->where('assigned_type', User::class)->where('assigned_to', $user->id)->count() > 0);
|
||||
|
||||
Event::assertDispatched(CheckoutableCheckedIn::class, 1);
|
||||
}
|
||||
|
|
|
@ -196,4 +196,31 @@ class AssetCheckinTest extends TestCase
|
|||
->assertSessionHas('error')
|
||||
->assertRedirect(route('hardware.show', ['hardware' => $asset->id]));
|
||||
}
|
||||
|
||||
public function testAssetCheckinPagePostIsRedirectedIfRedirectSelectionIsIndex()
|
||||
{
|
||||
$asset = Asset::factory()->assignedToUser()->create();
|
||||
|
||||
$this->actingAs(User::factory()->admin()->create())
|
||||
->from(route('hardware.index'))
|
||||
->post(route('hardware.checkin.store', $asset), [
|
||||
'redirect_option' => 'index',
|
||||
])
|
||||
->assertStatus(302)
|
||||
->assertRedirect(route('hardware.index'));
|
||||
}
|
||||
|
||||
public function testAssetCheckinPagePostIsRedirectedIfRedirectSelectionIsItem()
|
||||
{
|
||||
$asset = Asset::factory()->assignedToUser()->create();
|
||||
|
||||
$this->actingAs(User::factory()->admin()->create())
|
||||
->from(route('hardware.index'))
|
||||
->post(route('hardware.checkin.store', $asset), [
|
||||
'redirect_option' => 'item',
|
||||
])
|
||||
->assertStatus(302)
|
||||
->assertSessionHasNoErrors()
|
||||
->assertRedirect(route('hardware.show', ['hardware' => $asset->id]));
|
||||
}
|
||||
}
|
||||
|
|
51
tests/Feature/Checkins/Ui/ComponentCheckinTest.php
Normal file
51
tests/Feature/Checkins/Ui/ComponentCheckinTest.php
Normal file
|
@ -0,0 +1,51 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\Feature\Checkins\Ui;
|
||||
|
||||
use App\Models\Component;
|
||||
use App\Models\User;
|
||||
use Tests\TestCase;
|
||||
|
||||
class ComponentCheckinTest extends TestCase
|
||||
{
|
||||
public function testCheckingInComponentRequiresCorrectPermission()
|
||||
{
|
||||
$this->actingAs(User::factory()->create())
|
||||
->post(route('components.checkin.store', [
|
||||
'componentID' => Component::factory()->checkedOutToAsset()->create()->id,
|
||||
]))
|
||||
->assertForbidden();
|
||||
}
|
||||
|
||||
|
||||
public function testComponentCheckinPagePostIsRedirectedIfRedirectSelectionIsIndex()
|
||||
{
|
||||
$component = Component::factory()->checkedOutToAsset()->create();
|
||||
|
||||
$this->actingAs(User::factory()->admin()->create())
|
||||
->from(route('components.index'))
|
||||
->post(route('components.checkin.store', $component), [
|
||||
'redirect_option' => 'index',
|
||||
'checkin_qty' => 1,
|
||||
])
|
||||
->assertStatus(302)
|
||||
->assertRedirect(route('components.index'));
|
||||
}
|
||||
|
||||
public function testComponentCheckinPagePostIsRedirectedIfRedirectSelectionIsItem()
|
||||
{
|
||||
$component = Component::factory()->checkedOutToAsset()->create();
|
||||
|
||||
$this->actingAs(User::factory()->admin()->create())
|
||||
->from(route('components.index'))
|
||||
->post(route('components.checkin.store', $component), [
|
||||
'redirect_option' => 'item',
|
||||
'checkin_qty' => 1,
|
||||
])
|
||||
->assertStatus(302)
|
||||
->assertSessionHasNoErrors()
|
||||
->assertRedirect(route('components.show', ['component' => $component->id]));
|
||||
}
|
||||
|
||||
|
||||
}
|
21
tests/Feature/Checkins/Ui/LicenseCheckinTest.php
Normal file
21
tests/Feature/Checkins/Ui/LicenseCheckinTest.php
Normal file
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\Feature\Checkins\Ui;
|
||||
|
||||
use App\Models\LicenseSeat;
|
||||
use App\Models\User;
|
||||
use Tests\TestCase;
|
||||
|
||||
class LicenseCheckinTest extends TestCase
|
||||
{
|
||||
public function testCheckingInLicenseRequiresCorrectPermission()
|
||||
{
|
||||
$this->actingAs(User::factory()->create())
|
||||
->post(route('licenses.checkin.save', [
|
||||
'licenseId' => LicenseSeat::factory()->assignedToUser()->create()->id,
|
||||
]))
|
||||
->assertForbidden();
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -22,7 +22,7 @@ class AccessoryCheckoutTest extends TestCase
|
|||
{
|
||||
$this->actingAsForApi(User::factory()->checkoutAccessories()->create())
|
||||
->postJson(route('api.accessories.checkout', Accessory::factory()->create()), [
|
||||
// missing assigned_to
|
||||
// missing assigned_user, assigned_location, assigned_asset
|
||||
])
|
||||
->assertStatusMessageIs('error');
|
||||
}
|
||||
|
@ -31,7 +31,8 @@ class AccessoryCheckoutTest extends TestCase
|
|||
{
|
||||
$this->actingAsForApi(User::factory()->checkoutAccessories()->create())
|
||||
->postJson(route('api.accessories.checkout', Accessory::factory()->withoutItemsRemaining()->create()), [
|
||||
'assigned_to' => User::factory()->create()->id,
|
||||
'assigned_user' => User::factory()->create()->id,
|
||||
'checkout_to_type' => 'user'
|
||||
])
|
||||
->assertOk()
|
||||
->assertStatusMessageIs('error')
|
||||
|
@ -65,7 +66,8 @@ class AccessoryCheckoutTest extends TestCase
|
|||
|
||||
$this->actingAsForApi($admin)
|
||||
->postJson(route('api.accessories.checkout', $accessory), [
|
||||
'assigned_to' => $user->id,
|
||||
'assigned_user' => $user->id,
|
||||
'checkout_to_type' => 'user'
|
||||
])
|
||||
->assertOk()
|
||||
->assertStatusMessageIs('success')
|
||||
|
@ -73,7 +75,7 @@ class AccessoryCheckoutTest extends TestCase
|
|||
->assertJson(['messages' => trans('admin/accessories/message.checkout.success')])
|
||||
->json();
|
||||
|
||||
$this->assertTrue($accessory->users->contains($user));
|
||||
$this->assertTrue($accessory->checkouts()->where('assigned_type', User::class)->where('assigned_to', $user->id)->count() > 0);
|
||||
|
||||
$this->assertEquals(
|
||||
1,
|
||||
|
@ -96,7 +98,8 @@ class AccessoryCheckoutTest extends TestCase
|
|||
|
||||
$this->actingAsForApi($admin)
|
||||
->postJson(route('api.accessories.checkout', $accessory), [
|
||||
'assigned_to' => $user->id,
|
||||
'assigned_user' => $user->id,
|
||||
'checkout_to_type' => 'user',
|
||||
'checkout_qty' => 2,
|
||||
])
|
||||
->assertOk()
|
||||
|
@ -105,7 +108,7 @@ class AccessoryCheckoutTest extends TestCase
|
|||
->assertJson(['messages' => trans('admin/accessories/message.checkout.success')])
|
||||
->json();
|
||||
|
||||
$this->assertTrue($accessory->users->contains($user));
|
||||
$this->assertTrue($accessory->checkouts()->where('assigned_type', User::class)->where('assigned_to', $user->id)->count() > 0);
|
||||
|
||||
$this->assertEquals(
|
||||
1,
|
||||
|
@ -128,7 +131,8 @@ class AccessoryCheckoutTest extends TestCase
|
|||
|
||||
$this->actingAsForApi(User::factory()->checkoutAccessories()->create())
|
||||
->postJson(route('api.accessories.checkout', $accessory), [
|
||||
'assigned_to' => 'invalid-user-id',
|
||||
'assigned_user' => 'invalid-user-id',
|
||||
'checkout_to_type' => 'user',
|
||||
'note' => 'oh hi there',
|
||||
])
|
||||
->assertOk()
|
||||
|
@ -136,7 +140,7 @@ class AccessoryCheckoutTest extends TestCase
|
|||
->assertStatus(200)
|
||||
->json();
|
||||
|
||||
$this->assertFalse($accessory->users->contains($user));
|
||||
$this->assertFalse($accessory->checkouts()->where('assigned_type', User::class)->where('assigned_to', $user->id)->count() > 0);
|
||||
}
|
||||
|
||||
public function testUserSentNotificationUponCheckout()
|
||||
|
@ -148,7 +152,8 @@ class AccessoryCheckoutTest extends TestCase
|
|||
|
||||
$this->actingAsForApi(User::factory()->checkoutAccessories()->create())
|
||||
->postJson(route('api.accessories.checkout', $accessory), [
|
||||
'assigned_to' => $user->id,
|
||||
'assigned_user' => $user->id,
|
||||
'checkout_to_type' => 'user',
|
||||
]);
|
||||
|
||||
Notification::assertSentTo($user, CheckoutAccessoryNotification::class);
|
||||
|
@ -162,7 +167,8 @@ class AccessoryCheckoutTest extends TestCase
|
|||
|
||||
$this->actingAsForApi($actor)
|
||||
->postJson(route('api.accessories.checkout', $accessory), [
|
||||
'assigned_to' => $user->id,
|
||||
'assigned_user' => $user->id,
|
||||
'checkout_to_type' => 'user',
|
||||
'note' => 'oh hi there',
|
||||
]);
|
||||
|
||||
|
|
|
@ -4,6 +4,8 @@ namespace Tests\Feature\Checkouts\Ui;
|
|||
|
||||
use App\Models\Accessory;
|
||||
use App\Models\Actionlog;
|
||||
use App\Models\Asset;
|
||||
use App\Models\Location;
|
||||
use App\Models\User;
|
||||
use App\Notifications\CheckoutAccessoryNotification;
|
||||
use Illuminate\Support\Facades\Notification;
|
||||
|
@ -40,7 +42,8 @@ class AccessoryCheckoutTest extends TestCase
|
|||
$response = $this->actingAs(User::factory()->viewAccessories()->checkoutAccessories()->create())
|
||||
->from(route('accessories.checkout.show', $accessory))
|
||||
->post(route('accessories.checkout.store', $accessory), [
|
||||
'assigned_to' => User::factory()->create()->id,
|
||||
'assigned_user' => User::factory()->create()->id,
|
||||
'checkout_to_type' => 'user',
|
||||
])
|
||||
->assertStatus(302)
|
||||
->assertSessionHas('errors')
|
||||
|
@ -56,11 +59,12 @@ class AccessoryCheckoutTest extends TestCase
|
|||
|
||||
$this->actingAs(User::factory()->checkoutAccessories()->create())
|
||||
->post(route('accessories.checkout.store', $accessory), [
|
||||
'assigned_to' => $user->id,
|
||||
'assigned_user' => $user->id,
|
||||
'checkout_to_type' => 'user',
|
||||
'note' => 'oh hi there',
|
||||
]);
|
||||
|
||||
$this->assertTrue($accessory->users->contains($user));
|
||||
$this->assertTrue($accessory->checkouts()->where('assigned_type', User::class)->where('assigned_to', $user->id)->count() > 0);
|
||||
|
||||
$this->assertDatabaseHas('action_logs', [
|
||||
'action_type' => 'checkout',
|
||||
|
@ -80,12 +84,13 @@ class AccessoryCheckoutTest extends TestCase
|
|||
$this->actingAs(User::factory()->checkoutAccessories()->create())
|
||||
->from(route('accessories.checkout.show', $accessory))
|
||||
->post(route('accessories.checkout.store', $accessory), [
|
||||
'assigned_to' => $user->id,
|
||||
'assigned_user' => $user->id,
|
||||
'checkout_to_type' => 'user',
|
||||
'checkout_qty' => 3,
|
||||
'note' => 'oh hi there',
|
||||
]);
|
||||
|
||||
$this->assertTrue($accessory->users->contains($user));
|
||||
$this->assertTrue($accessory->checkouts()->where('assigned_type', User::class)->where('assigned_to', $user->id)->count() > 0);
|
||||
|
||||
$this->assertDatabaseHas('action_logs', [
|
||||
'action_type' => 'checkout',
|
||||
|
@ -97,6 +102,58 @@ class AccessoryCheckoutTest extends TestCase
|
|||
]);
|
||||
}
|
||||
|
||||
public function testAccessoryCanBeCheckedOutToLocationWithQuantity()
|
||||
{
|
||||
$accessory = Accessory::factory()->create(['qty'=>5]);
|
||||
$location = Location::factory()->create();
|
||||
|
||||
$this->actingAs(User::factory()->checkoutAccessories()->create())
|
||||
->from(route('accessories.checkout.show', $accessory))
|
||||
->post(route('accessories.checkout.store', $accessory), [
|
||||
'assigned_location' => $location->id,
|
||||
'checkout_to_type' => 'location',
|
||||
'checkout_qty' => 3,
|
||||
'note' => 'oh hi there',
|
||||
]);
|
||||
|
||||
$this->assertTrue($accessory->checkouts()->where('assigned_type', Location::class)->where('assigned_to', $location->id)->count() > 0);
|
||||
|
||||
$this->assertDatabaseHas('action_logs', [
|
||||
'action_type' => 'checkout',
|
||||
'target_id' => $location->id,
|
||||
'target_type' => Location::class,
|
||||
'item_id' => $accessory->id,
|
||||
'item_type' => Accessory::class,
|
||||
'note' => 'oh hi there',
|
||||
]);
|
||||
}
|
||||
|
||||
public function testAccessoryCanBeCheckedOutToAssetWithQuantity()
|
||||
{
|
||||
$accessory = Accessory::factory()->create(['qty'=>5]);
|
||||
$asset = Asset::factory()->create();
|
||||
|
||||
$this->actingAs(User::factory()->checkoutAccessories()->create())
|
||||
->from(route('accessories.checkout.show', $accessory))
|
||||
->post(route('accessories.checkout.store', $accessory), [
|
||||
'assigned_asset' => $asset->id,
|
||||
'checkout_to_type' => 'asset',
|
||||
'checkout_qty' => 3,
|
||||
'note' => 'oh hi there',
|
||||
]);
|
||||
|
||||
$this->assertTrue($accessory->checkouts()->where('assigned_type', Asset::class)->where('assigned_to', $asset->id)->count() > 0);
|
||||
|
||||
$this->assertDatabaseHas('action_logs', [
|
||||
'action_type' => 'checkout',
|
||||
'target_id' => $asset->id,
|
||||
'target_type' => Asset::class,
|
||||
'item_id' => $accessory->id,
|
||||
'item_type' => Accessory::class,
|
||||
'note' => 'oh hi there',
|
||||
]);
|
||||
}
|
||||
|
||||
public function testUserSentNotificationUponCheckout()
|
||||
{
|
||||
Notification::fake();
|
||||
|
@ -107,7 +164,8 @@ class AccessoryCheckoutTest extends TestCase
|
|||
$this->actingAs(User::factory()->checkoutAccessories()->create())
|
||||
->from(route('accessories.checkout.show', $accessory))
|
||||
->post(route('accessories.checkout.store', $accessory), [
|
||||
'assigned_to' => $user->id,
|
||||
'assigned_user' => $user->id,
|
||||
'checkout_to_type' => 'user',
|
||||
]);
|
||||
|
||||
Notification::assertSentTo($user, CheckoutAccessoryNotification::class);
|
||||
|
@ -122,7 +180,8 @@ class AccessoryCheckoutTest extends TestCase
|
|||
$this->actingAs($actor)
|
||||
->from(route('accessories.checkout.show', $accessory))
|
||||
->post(route('accessories.checkout.store', $accessory), [
|
||||
'assigned_to' => $user->id,
|
||||
'assigned_user' => $user->id,
|
||||
'checkout_to_type' => 'user',
|
||||
'note' => 'oh hi there',
|
||||
]);
|
||||
|
||||
|
@ -140,4 +199,54 @@ class AccessoryCheckoutTest extends TestCase
|
|||
'Log entry either does not exist or there are more than expected'
|
||||
);
|
||||
}
|
||||
|
||||
public function testAccessoryCheckoutPagePostIsRedirectedIfRedirectSelectionIsIndex()
|
||||
{
|
||||
$accessory = Accessory::factory()->create();
|
||||
|
||||
$this->actingAs(User::factory()->admin()->create())
|
||||
->from(route('accessories.index'))
|
||||
->post(route('accessories.checkout.store', $accessory), [
|
||||
'assigned_user' => User::factory()->create()->id,
|
||||
'checkout_to_type' => 'user',
|
||||
'redirect_option' => 'index',
|
||||
'assigned_qty' => 1,
|
||||
])
|
||||
->assertStatus(302)
|
||||
->assertRedirect(route('accessories.index'));
|
||||
}
|
||||
|
||||
public function testAccessoryCheckoutPagePostIsRedirectedIfRedirectSelectionIsItem()
|
||||
{
|
||||
$accessory = Accessory::factory()->create();
|
||||
|
||||
$this->actingAs(User::factory()->admin()->create())
|
||||
->from(route('accessories.index'))
|
||||
->post(route('accessories.checkout.store' , $accessory), [
|
||||
'assigned_user' => User::factory()->create()->id,
|
||||
'checkout_to_type' => 'user',
|
||||
'redirect_option' => 'item',
|
||||
'assigned_qty' => 1,
|
||||
])
|
||||
->assertStatus(302)
|
||||
->assertSessionHasNoErrors()
|
||||
->assertRedirect(route('accessories.show', ['accessory' => $accessory->id]));
|
||||
}
|
||||
|
||||
public function testAccessoryCheckoutPagePostIsRedirectedIfRedirectSelectionIsTarget()
|
||||
{
|
||||
$user = User::factory()->create();
|
||||
$accessory = Accessory::factory()->create();
|
||||
|
||||
$this->actingAs(User::factory()->admin()->create())
|
||||
->from(route('accessories.index'))
|
||||
->post(route('accessories.checkout.store' , $accessory), [
|
||||
'assigned_user' => $user->id,
|
||||
'checkout_to_type' => 'user',
|
||||
'redirect_option' => 'target',
|
||||
'assigned_qty' => 1,
|
||||
])
|
||||
->assertStatus(302)
|
||||
->assertRedirect(route('users.show', ['user' => $user]));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
namespace Tests\Feature\Checkouts\Ui;
|
||||
|
||||
use App\Events\CheckoutableCheckedOut;
|
||||
use App\Models\Accessory;
|
||||
use App\Models\Asset;
|
||||
use App\Models\Company;
|
||||
use App\Models\LicenseSeat;
|
||||
|
@ -251,20 +252,85 @@ class AssetCheckoutTest extends TestCase
|
|||
->assertRedirect(route('hardware.show',['hardware' => $asset->id]));
|
||||
}
|
||||
|
||||
public function testAssetCheckoutPagePostIsRedirectedIfModelIsInvalid()
|
||||
public function testAssetCheckoutPagePostIsRedirectedIfRedirectSelectionIsIndex()
|
||||
{
|
||||
$asset = Asset::factory()->create();
|
||||
$asset->model_id = 0;
|
||||
$asset->forceSave();
|
||||
$user = User::factory()->create();
|
||||
|
||||
|
||||
$this->actingAs(User::factory()->admin()->create())
|
||||
->from(route('hardware.checkout.create', $asset))
|
||||
->post(route('hardware.checkout.store', $asset), [
|
||||
'checkout_to_type' => 'user',
|
||||
'assigned_user' => $user->id,
|
||||
'assigned_user' => User::factory()->create()->id,
|
||||
'redirect_option' => 'index',
|
||||
])
|
||||
->assertStatus(302)
|
||||
->assertSessionHas('error')
|
||||
->assertRedirect(route('hardware.index'));
|
||||
}
|
||||
|
||||
public function testAssetCheckoutPagePostIsRedirectedIfRedirectSelectionIsItem()
|
||||
{
|
||||
$asset = Asset::factory()->create();
|
||||
|
||||
$this->actingAs(User::factory()->admin()->create())
|
||||
->from(route('hardware.checkout.create', $asset))
|
||||
->post(route('hardware.checkout.store' , $asset), [
|
||||
'checkout_to_type' => 'user',
|
||||
'assigned_user' => User::factory()->create()->id,
|
||||
'redirect_option' => 'item',
|
||||
])
|
||||
->assertStatus(302)
|
||||
->assertSessionHasNoErrors()
|
||||
->assertRedirect(route('hardware.show', ['hardware' => $asset->id]));
|
||||
}
|
||||
|
||||
public function testAssetCheckoutPagePostIsRedirectedIfRedirectSelectionIsUserTarget()
|
||||
{
|
||||
$user = User::factory()->create();
|
||||
$asset = Asset::factory()->create();
|
||||
|
||||
$this->actingAs(User::factory()->admin()->create())
|
||||
->from(route('hardware.checkout.create', $asset))
|
||||
->post(route('hardware.checkout.store' , $asset), [
|
||||
'checkout_to_type' => 'user',
|
||||
'assigned_user' => $user->id,
|
||||
'redirect_option' => 'target',
|
||||
'assigned_qty' => 1,
|
||||
])
|
||||
->assertStatus(302)
|
||||
->assertRedirect(route('users.show', ['user' => $user]));
|
||||
}
|
||||
|
||||
public function testAssetCheckoutPagePostIsRedirectedIfRedirectSelectionIsAssetTarget()
|
||||
{
|
||||
$target = Asset::factory()->create();
|
||||
$asset = Asset::factory()->create();
|
||||
|
||||
$this->actingAs(User::factory()->admin()->create())
|
||||
->from(route('hardware.checkout.create', $asset))
|
||||
->post(route('hardware.checkout.store' , $asset), [
|
||||
'checkout_to_type' => 'asset',
|
||||
'assigned_asset' => $target->id,
|
||||
'redirect_option' => 'target',
|
||||
'assigned_qty' => 1,
|
||||
])
|
||||
->assertStatus(302)
|
||||
->assertRedirect(route('hardware.show', ['hardware' => $target]));
|
||||
}
|
||||
|
||||
public function testAssetCheckoutPagePostIsRedirectedIfRedirectSelectionIsLocationTarget()
|
||||
{
|
||||
$target = Location::factory()->create();
|
||||
$asset = Asset::factory()->create();
|
||||
|
||||
$this->actingAs(User::factory()->admin()->create())
|
||||
->from(route('hardware.checkout.create', $asset))
|
||||
->post(route('hardware.checkout.store' , $asset), [
|
||||
'checkout_to_type' => 'location',
|
||||
'assigned_location' => $target->id,
|
||||
'redirect_option' => 'target',
|
||||
'assigned_qty' => 1,
|
||||
])
|
||||
->assertStatus(302)
|
||||
->assertRedirect(route('locations.show', ['location' => $target]));
|
||||
}
|
||||
}
|
||||
|
|
68
tests/Feature/Checkouts/Ui/ComponentsCheckoutTest.php
Normal file
68
tests/Feature/Checkouts/Ui/ComponentsCheckoutTest.php
Normal file
|
@ -0,0 +1,68 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\Feature\Checkins\Ui;
|
||||
|
||||
use App\Models\Asset;
|
||||
use App\Models\Component;
|
||||
use App\Models\User;
|
||||
use Tests\TestCase;
|
||||
|
||||
class ComponentsCheckoutTest extends TestCase
|
||||
{
|
||||
public function testCheckingOutComponentRequiresCorrectPermission()
|
||||
{
|
||||
$this->actingAs(User::factory()->create())
|
||||
->post(route('components.checkout.store', [
|
||||
'componentID' => Component::factory()->checkedOutToAsset()->create()->id,
|
||||
]))
|
||||
->assertForbidden();
|
||||
}
|
||||
|
||||
public function testComponentCheckoutPagePostIsRedirectedIfRedirectSelectionIsIndex()
|
||||
{
|
||||
$component = Component::factory()->create();
|
||||
|
||||
$this->actingAs(User::factory()->admin()->create())
|
||||
->from(route('components.index'))
|
||||
->post(route('components.checkout.store', $component), [
|
||||
'asset_id' => Asset::factory()->create()->id,
|
||||
'redirect_option' => 'index',
|
||||
'assigned_qty' => 1,
|
||||
])
|
||||
->assertStatus(302)
|
||||
->assertRedirect(route('components.index'));
|
||||
}
|
||||
|
||||
public function testComponentCheckoutPagePostIsRedirectedIfRedirectSelectionIsItem()
|
||||
{
|
||||
$component = Component::factory()->create();
|
||||
|
||||
$this->actingAs(User::factory()->admin()->create())
|
||||
->from(route('components.index'))
|
||||
->post(route('components.checkout.store' , $component), [
|
||||
'asset_id' => Asset::factory()->create()->id,
|
||||
'redirect_option' => 'item',
|
||||
'assigned_qty' => 1,
|
||||
])
|
||||
->assertStatus(302)
|
||||
->assertRedirect(route('components.show', ['component' => $component->id]));
|
||||
}
|
||||
|
||||
public function testComponentCheckoutPagePostIsRedirectedIfRedirectSelectionIsTarget()
|
||||
{
|
||||
$asset = Asset::factory()->create();
|
||||
$component = Component::factory()->create();
|
||||
|
||||
$this->actingAs(User::factory()->admin()->create())
|
||||
->from(route('components.index'))
|
||||
->post(route('components.checkout.store' , $component), [
|
||||
'asset_id' => $asset->id,
|
||||
'redirect_option' => 'target',
|
||||
'assigned_qty' => 1,
|
||||
])
|
||||
->assertStatus(302)
|
||||
->assertRedirect(route('hardware.show', ['hardware' => $asset]));
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -3,6 +3,8 @@
|
|||
namespace Tests\Feature\Checkouts\Ui;
|
||||
|
||||
use App\Models\Actionlog;
|
||||
use App\Models\Asset;
|
||||
use App\Models\Component;
|
||||
use App\Models\Consumable;
|
||||
use App\Models\User;
|
||||
use App\Notifications\CheckoutConsumableNotification;
|
||||
|
@ -90,4 +92,51 @@ class ConsumableCheckoutTest extends TestCase
|
|||
'Log entry either does not exist or there are more than expected'
|
||||
);
|
||||
}
|
||||
|
||||
public function testConsumableCheckoutPagePostIsRedirectedIfRedirectSelectionIsIndex()
|
||||
{
|
||||
$consumable = Consumable::factory()->create();
|
||||
|
||||
$this->actingAs(User::factory()->admin()->create())
|
||||
->from(route('consumables.index'))
|
||||
->post(route('consumables.checkout.store', $consumable), [
|
||||
'assigned_to' => User::factory()->create()->id,
|
||||
'redirect_option' => 'index',
|
||||
'assigned_qty' => 1,
|
||||
])
|
||||
->assertStatus(302)
|
||||
->assertRedirect(route('consumables.index'));
|
||||
}
|
||||
|
||||
public function testConsumableCheckoutPagePostIsRedirectedIfRedirectSelectionIsItem()
|
||||
{
|
||||
$consumable = Consumable::factory()->create();
|
||||
|
||||
$this->actingAs(User::factory()->admin()->create())
|
||||
->from(route('consumables.index'))
|
||||
->post(route('consumables.checkout.store' , $consumable), [
|
||||
'assigned_to' => User::factory()->create()->id,
|
||||
'redirect_option' => 'item',
|
||||
'assigned_qty' => 1,
|
||||
])
|
||||
->assertStatus(302)
|
||||
->assertRedirect(route('consumables.show', ['consumable' => $consumable->id]));
|
||||
}
|
||||
|
||||
public function testConsumableCheckoutPagePostIsRedirectedIfRedirectSelectionIsTarget()
|
||||
{
|
||||
$user = User::factory()->create();
|
||||
$consumable = Consumable::factory()->create();
|
||||
|
||||
$this->actingAs(User::factory()->admin()->create())
|
||||
->from(route('components.index'))
|
||||
->post(route('consumables.checkout.store' , $consumable), [
|
||||
'assigned_to' => $user->id,
|
||||
'redirect_option' => 'target',
|
||||
'assigned_qty' => 1,
|
||||
])
|
||||
->assertStatus(302)
|
||||
->assertRedirect(route('users.show', ['user' => $user]));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -56,4 +56,62 @@ class LicenseCheckoutTest extends TestCase
|
|||
'note' => 'oh hi there',
|
||||
]);
|
||||
}
|
||||
|
||||
public function testLicenseCheckoutPagePostIsRedirectedIfRedirectSelectionIsIndex()
|
||||
{
|
||||
$license = License::factory()->create();
|
||||
|
||||
$this->actingAs(User::factory()->admin()->create())
|
||||
->from(route('licenses.checkout', ['licenseId' => $license->id]))
|
||||
->post(route('licenses.checkout', ['licenseId' => $license->id]), [
|
||||
'assigned_to' => User::factory()->create()->id,
|
||||
'redirect_option' => 'index',
|
||||
'assigned_qty' => 1,
|
||||
])
|
||||
->assertStatus(302)
|
||||
->assertRedirect(route('licenses.index'));
|
||||
}
|
||||
|
||||
public function testLicenseCheckoutPagePostIsRedirectedIfRedirectSelectionIsItem()
|
||||
{
|
||||
$license = License::factory()->create();
|
||||
|
||||
$this->actingAs(User::factory()->admin()->create())
|
||||
->from(route('licenses.checkout', ['licenseId' => $license->id]))
|
||||
->post(route('licenses.checkout' , ['licenseId' => $license->id]), [
|
||||
'assigned_to' => User::factory()->create()->id,
|
||||
'redirect_option' => 'item',
|
||||
])
|
||||
->assertStatus(302)
|
||||
->assertRedirect(route('licenses.show', ['license' => $license->id]));
|
||||
}
|
||||
|
||||
public function testLicenseCheckoutPagePostIsRedirectedIfRedirectSelectionIsUserTarget()
|
||||
{
|
||||
$user = User::factory()->create();
|
||||
$license = License::factory()->create();
|
||||
|
||||
$this->actingAs(User::factory()->admin()->create())
|
||||
->from(route('licenses.checkout', ['licenseId' => $license->id]))
|
||||
->post(route('licenses.checkout' , $license), [
|
||||
'assigned_to' => $user->id,
|
||||
'redirect_option' => 'target',
|
||||
])
|
||||
->assertStatus(302)
|
||||
->assertRedirect(route('users.show', ['user' => $user->id]));
|
||||
}
|
||||
public function testLicenseCheckoutPagePostIsRedirectedIfRedirectSelectionIsAssetTarget()
|
||||
{
|
||||
$asset = Asset::factory()->create();
|
||||
$license = License::factory()->create();
|
||||
|
||||
$this->actingAs(User::factory()->admin()->create())
|
||||
->from(route('licenses.checkout', ['licenseId' => $license->id]))
|
||||
->post(route('licenses.checkout' , $license), [
|
||||
'asset_id' => $asset->id,
|
||||
'redirect_option' => 'target',
|
||||
])
|
||||
->assertStatus(302)
|
||||
->assertRedirect(route('hardware.show', ['hardware' => $asset->id]));
|
||||
}
|
||||
}
|
||||
|
|
42
tests/Feature/Licenses/Ui/CreateLicenseTest.php
Normal file
42
tests/Feature/Licenses/Ui/CreateLicenseTest.php
Normal file
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\Feature\Consumables\Ui;
|
||||
|
||||
use App\Models\AssetModel;
|
||||
use App\Models\Category;
|
||||
use App\Models\License;
|
||||
use App\Models\Depreciation;
|
||||
use App\Models\User;
|
||||
use Tests\TestCase;
|
||||
|
||||
class CreateLicenseTest extends TestCase
|
||||
{
|
||||
public function testPermissionRequiredToViewLicense()
|
||||
{
|
||||
$license = License::factory()->create();
|
||||
$this->actingAs(User::factory()->create())
|
||||
->get(route('licenses.create', $license))
|
||||
->assertForbidden();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function testLicenseWithoutPurchaseDateFailsValidation()
|
||||
{
|
||||
$response = $this->actingAs(User::factory()->superuser()->create())
|
||||
->from(route('licenses.create'))
|
||||
->post(route('licenses.store'), [
|
||||
'name' => 'Test Invalid License',
|
||||
'seats' => '10',
|
||||
'category_id' => Category::factory()->forLicenses()->create()->id,
|
||||
'depreciation_id' => Depreciation::factory()->create()->id
|
||||
]);
|
||||
$response->assertStatus(302);
|
||||
$response->assertRedirect(route('licenses.create'));
|
||||
$response->assertInvalid(['purchase_date']);
|
||||
$response->assertSessionHasErrors(['purchase_date']);
|
||||
$this->followRedirects($response)->assertSee(trans('general.error'));
|
||||
$this->assertFalse(AssetModel::where('name', 'Test Invalid License')->exists());
|
||||
|
||||
}
|
||||
}
|
31
tests/Feature/Licenses/Ui/LicenseViewTest.php
Normal file
31
tests/Feature/Licenses/Ui/LicenseViewTest.php
Normal file
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\Feature\Consumables\Ui;
|
||||
|
||||
use App\Models\License;
|
||||
use App\Models\Depreciation;
|
||||
use App\Models\User;
|
||||
use Tests\TestCase;
|
||||
|
||||
class LicenseViewTest extends TestCase
|
||||
{
|
||||
public function testPermissionRequiredToViewLicense()
|
||||
{
|
||||
$license = License::factory()->create();
|
||||
$this->actingAs(User::factory()->create())
|
||||
->get(route('licenses.show', $license))
|
||||
->assertForbidden();
|
||||
}
|
||||
|
||||
public function testLicenseWithPurchaseDateDepreciatesCorrectly()
|
||||
{
|
||||
$depreciation = Depreciation::factory()->create(['months' => 12]);
|
||||
$license = License::factory()->create(['depreciation_id' => $depreciation->id, 'purchase_date' => '2020-01-01']);
|
||||
$this->actingAs(User::factory()->superuser()->create())
|
||||
->get(route('licenses.show', $license))
|
||||
->assertOk()
|
||||
->assertSee([
|
||||
'2021-01-01'
|
||||
], false);
|
||||
}
|
||||
}
|
44
tests/Feature/Locations/Api/LocationsViewTest.php
Normal file
44
tests/Feature/Locations/Api/LocationsViewTest.php
Normal file
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\Feature\Consumables\Api;
|
||||
|
||||
use App\Models\Location;
|
||||
use App\Models\Asset;
|
||||
use App\Models\User;
|
||||
use Tests\TestCase;
|
||||
|
||||
class LocationsViewTest extends TestCase
|
||||
{
|
||||
public function testViewingLocationRequiresPermission()
|
||||
{
|
||||
$location = Location::factory()->create();
|
||||
$this->actingAsForApi(User::factory()->create())
|
||||
->getJson(route('api.locations.show', $location->id))
|
||||
->assertForbidden();
|
||||
}
|
||||
|
||||
public function testViewingLocationAssetIndexRequiresPermission()
|
||||
{
|
||||
$location = Location::factory()->create();
|
||||
$this->actingAsForApi(User::factory()->create())
|
||||
->getJson(route('api.locations.viewassets', $location->id))
|
||||
->assertForbidden();
|
||||
}
|
||||
|
||||
public function testViewingLocationAssetIndex()
|
||||
{
|
||||
$location = Location::factory()->create();
|
||||
Asset::factory()->count(3)->assignedToLocation($location)->create();
|
||||
|
||||
$this->actingAsForApi(User::factory()->superuser()->create())
|
||||
->getJson(route('api.locations.viewassets', $location->id))
|
||||
->assertOk()
|
||||
->assertJsonStructure([
|
||||
'total',
|
||||
'rows',
|
||||
])
|
||||
->assertJson([
|
||||
'total' => 3,
|
||||
]);
|
||||
}
|
||||
}
|
|
@ -31,46 +31,135 @@ class HelperTest extends TestCase
|
|||
public function testGetRedirectOptionMethod()
|
||||
{
|
||||
$test_data = [
|
||||
'Option 2: redirect for user assigned to ' => [
|
||||
'Option target: redirect for user assigned to ' => [
|
||||
'request' =>(object) ['assigned_user' => 22],
|
||||
'id' => 1,
|
||||
'checkout_to_type' => 'user',
|
||||
'redirect_option' => 2,
|
||||
'redirect_option' => 'target',
|
||||
'table' => 'Assets',
|
||||
'route' => route('users.show', 22),
|
||||
],
|
||||
'Option 2: redirect location assigned to ' => [
|
||||
'Option target: redirect location assigned to ' => [
|
||||
'request' =>(object) ['assigned_location' => 10],
|
||||
'id' => 2,
|
||||
'checkout_to_type' => 'location',
|
||||
'redirect_option' => 2,
|
||||
'redirect_option' => 'target',
|
||||
'table' => 'Locations',
|
||||
'route' => route('locations.show', 10),
|
||||
],
|
||||
'Option 2: redirect back to asset assigned to ' => [
|
||||
'Option target: redirect back to asset assigned to ' => [
|
||||
'request' =>(object) ['assigned_asset' => 101],
|
||||
'id' => 3,
|
||||
'checkout_to_type' => 'asset',
|
||||
'redirect_option' => 2,
|
||||
'redirect_option' => 'target',
|
||||
'table' => 'Assets',
|
||||
'route' => route('hardware.show', 101),
|
||||
],
|
||||
'Option 1: redirect back to asset ' => [
|
||||
'Option item: redirect back to asset ' => [
|
||||
'request' =>(object) ['assigned_asset' => null],
|
||||
'id' => 999,
|
||||
'checkout_to_type' => null,
|
||||
'redirect_option' => 1,
|
||||
'redirect_option' => 'item',
|
||||
'table' => 'Assets',
|
||||
'route' => route('hardware.show', 999),
|
||||
],
|
||||
'Option 0: redirect back to index ' => [
|
||||
'Option index: redirect back to asset index ' => [
|
||||
'request' =>(object) ['assigned_asset' => null],
|
||||
'id' => null,
|
||||
'checkout_to_type' => null,
|
||||
'redirect_option' => 0,
|
||||
'redirect_option' => 'index',
|
||||
'table' => 'Assets',
|
||||
'route' => route('hardware.index'),
|
||||
],
|
||||
|
||||
'Option item: redirect back to user ' => [
|
||||
'request' =>(object) ['assigned_asset' => null],
|
||||
'id' => 999,
|
||||
'checkout_to_type' => null,
|
||||
'redirect_option' => 'item',
|
||||
'table' => 'Users',
|
||||
'route' => route('users.show', 999),
|
||||
],
|
||||
|
||||
'Option index: redirect back to user index ' => [
|
||||
'request' =>(object) ['assigned_asset' => null],
|
||||
'id' => null,
|
||||
'checkout_to_type' => null,
|
||||
'redirect_option' => 'index',
|
||||
'table' => 'Users',
|
||||
'route' => route('users.index'),
|
||||
],
|
||||
|
||||
'Option item: redirect back to license ' => [
|
||||
'request' =>(object) ['assigned_asset' => null],
|
||||
'id' => 999,
|
||||
'checkout_to_type' => null,
|
||||
'redirect_option' => 'item',
|
||||
'table' => 'Licenses',
|
||||
'route' => route('licenses.show', 999),
|
||||
],
|
||||
|
||||
'Option index: redirect back to license index ' => [
|
||||
'request' =>(object) ['assigned_asset' => null],
|
||||
'id' => null,
|
||||
'checkout_to_type' => null,
|
||||
'redirect_option' => 'index',
|
||||
'table' => 'Licenses',
|
||||
'route' => route('licenses.index'),
|
||||
],
|
||||
|
||||
'Option item: redirect back to accessory list ' => [
|
||||
'request' =>(object) ['assigned_asset' => null],
|
||||
'id' => 999,
|
||||
'checkout_to_type' => null,
|
||||
'redirect_option' => 'item',
|
||||
'table' => 'Accessories',
|
||||
'route' => route('accessories.show', 999),
|
||||
],
|
||||
|
||||
'Option index: redirect back to accessory index ' => [
|
||||
'request' =>(object) ['assigned_asset' => null],
|
||||
'id' => null,
|
||||
'checkout_to_type' => null,
|
||||
'redirect_option' => 'index',
|
||||
'table' => 'Accessories',
|
||||
'route' => route('accessories.index'),
|
||||
],
|
||||
'Option item: redirect back to consumable ' => [
|
||||
'request' =>(object) ['assigned_asset' => null],
|
||||
'id' => 999,
|
||||
'checkout_to_type' => null,
|
||||
'redirect_option' => 'item',
|
||||
'table' => 'Consumables',
|
||||
'route' => route('consumables.show', 999),
|
||||
],
|
||||
|
||||
'Option index: redirect back to consumables index ' => [
|
||||
'request' =>(object) ['assigned_asset' => null],
|
||||
'id' => null,
|
||||
'checkout_to_type' => null,
|
||||
'redirect_option' => 'index',
|
||||
'table' => 'Consumables',
|
||||
'route' => route('consumables.index'),
|
||||
],
|
||||
|
||||
'Option item: redirect back to component ' => [
|
||||
'request' =>(object) ['assigned_asset' => null],
|
||||
'id' => 999,
|
||||
'checkout_to_type' => null,
|
||||
'redirect_option' => 'item',
|
||||
'table' => 'Components',
|
||||
'route' => route('components.show', 999),
|
||||
],
|
||||
|
||||
'Option index: redirect back to component index ' => [
|
||||
'request' =>(object) ['assigned_asset' => null],
|
||||
'id' => null,
|
||||
'checkout_to_type' => null,
|
||||
'redirect_option' => 'index',
|
||||
'table' => 'Components',
|
||||
'route' => route('components.index'),
|
||||
],
|
||||
];
|
||||
|
||||
foreach ($test_data as $scenario => $data ) {
|
||||
|
@ -78,7 +167,7 @@ class HelperTest extends TestCase
|
|||
Session::put('redirect_option', $data['redirect_option']);
|
||||
Session::put('checkout_to_type', $data['checkout_to_type']);
|
||||
|
||||
$redirect = Helper::getRedirectOption($data['request'],$data['id'], $data['table']);
|
||||
$redirect = redirect()->to(Helper::getRedirectOption($data['request'],$data['id'], $data['table']));
|
||||
|
||||
$this->assertInstanceOf(RedirectResponse::class, $redirect);
|
||||
$this->assertEquals($data['route'], $redirect->getTargetUrl(), $scenario.'failed.');
|
||||
|
|
111
webpack.mix.js
111
webpack.mix.js
|
@ -1,4 +1,5 @@
|
|||
const mix = require("laravel-mix");
|
||||
const fs = require("node:fs");
|
||||
|
||||
// This generates a file called app.css, which we use
|
||||
// later on to build all.css
|
||||
|
@ -68,67 +69,30 @@ mix
|
|||
"./public/js/build/app.js" //because of compiling - this does not work very well :(
|
||||
)
|
||||
|
||||
var skins = fs.readdirSync("resources/assets/less/skins");
|
||||
|
||||
// Convert the skins to CSS
|
||||
mix.less(
|
||||
"./resources/assets/less/skins/skin-blue.less",
|
||||
"css/dist/skins",
|
||||
);
|
||||
mix.less(
|
||||
"./resources/assets/less/skins/skin-red.less",
|
||||
"css/dist/skins",
|
||||
);
|
||||
mix.less(
|
||||
"./resources/assets/less/skins/skin-contrast.less",
|
||||
"css/dist/skins",
|
||||
);
|
||||
mix.less(
|
||||
"./resources/assets/less/skins/skin-green.less",
|
||||
"css/dist/skins",
|
||||
);
|
||||
mix.less(
|
||||
"./resources/assets/less/skins/skin-green-dark.less",
|
||||
"css/dist/skins",
|
||||
);
|
||||
mix.less(
|
||||
"./resources/assets/less/skins/skin-black.less",
|
||||
"css/dist/skins",
|
||||
);
|
||||
mix.less(
|
||||
"./resources/assets/less/skins/skin-black-dark.less",
|
||||
"css/dist/skins",
|
||||
);
|
||||
mix.less(
|
||||
"./resources/assets/less/skins/skin-red-dark.less",
|
||||
"css/dist/skins",
|
||||
);
|
||||
mix.less(
|
||||
"./resources/assets/less/skins/skin-purple.less",
|
||||
"css/dist/skins",
|
||||
);
|
||||
mix.less(
|
||||
"./resources/assets/less/skins/skin-purple-dark.less",
|
||||
"css/dist/skins",
|
||||
);
|
||||
mix.less(
|
||||
"./resources/assets/less/skins/skin-yellow.less",
|
||||
"css/dist/skins",
|
||||
);
|
||||
mix.less(
|
||||
"./resources/assets/less/skins/skin-yellow-dark.less",
|
||||
"css/dist/skins",
|
||||
);
|
||||
mix.less(
|
||||
"./resources/assets/less/skins/skin-blue-dark.less",
|
||||
"css/dist/skins",
|
||||
);
|
||||
mix.less(
|
||||
"./resources/assets/less/skins/skin-orange-dark.less",
|
||||
"css/dist/skins",
|
||||
);
|
||||
mix.less(
|
||||
"./resources/assets/less/skins/skin-orange.less",
|
||||
"css/dist/skins",
|
||||
);
|
||||
for (var i in skins) {
|
||||
mix.less(
|
||||
"resources/assets/less/skins/" + skins[i],
|
||||
"css/dist/skins"
|
||||
)
|
||||
}
|
||||
|
||||
var css_skins = fs.readdirSync("public/css/dist/skins");
|
||||
for (var i in css_skins) {
|
||||
if (css_skins[i].endsWith(".min.css")) {
|
||||
//don't minify already minified skinns
|
||||
continue;
|
||||
}
|
||||
if (css_skins[i].endsWith(".css")) {
|
||||
// only minify files ending with '.css'
|
||||
mix.minify("public/css/dist/skins/" + css_skins[i]).version();
|
||||
}
|
||||
//TODO - if we only ever use the minified versions, this could be simplified down to one line (above)
|
||||
// but it stays like this so we have the minified and non-minified versions of the skins
|
||||
// right now the code seems to use the un-minified skins
|
||||
}
|
||||
|
||||
/**
|
||||
* Combine bootstrap table css
|
||||
|
@ -163,7 +127,7 @@ mix.combine(
|
|||
"./node_modules/ekko-lightbox/dist/ekko-lightbox.js",
|
||||
"./resources/assets/js/extensions/pGenerator.jquery.js",
|
||||
"./node_modules/chart.js/dist/Chart.js",
|
||||
"./resources/assets/js/signature_pad.js",
|
||||
"./resources/assets/js/signature_pad.js", //dupe?
|
||||
"./node_modules/jquery-validation/dist/jquery.validate.js",
|
||||
"./node_modules/list.js/dist/list.js",
|
||||
"./node_modules/clipboard/dist/clipboard.js",
|
||||
|
@ -200,27 +164,4 @@ mix
|
|||
["./public/js/build/vendor.js", "./public/js/build/app.js"],
|
||||
"./public/js/dist/all.js"
|
||||
)
|
||||
.version();
|
||||
|
||||
/**
|
||||
* Copy, minify and version skins
|
||||
*/
|
||||
mix
|
||||
.minify([
|
||||
"./public/css/dist/skins/skin-green.css",
|
||||
"./public/css/dist/skins/skin-green-dark.css",
|
||||
"./public/css/dist/skins/skin-black.css",
|
||||
"./public/css/dist/skins/skin-black-dark.css",
|
||||
"./public/css/dist/skins/skin-blue.css",
|
||||
"./public/css/dist/skins/skin-blue-dark.css",
|
||||
"./public/css/dist/skins/skin-yellow.css",
|
||||
"./public/css/dist/skins/skin-yellow-dark.css",
|
||||
"./public/css/dist/skins/skin-red.css",
|
||||
"./public/css/dist/skins/skin-red-dark.css",
|
||||
"./public/css/dist/skins/skin-purple.css",
|
||||
"./public/css/dist/skins/skin-purple-dark.css",
|
||||
"./public/css/dist/skins/skin-orange.css",
|
||||
"./public/css/dist/skins/skin-orange-dark.css",
|
||||
"./public/css/dist/skins/skin-contrast.css",
|
||||
])
|
||||
.version();
|
||||
.version();
|
Loading…
Reference in a new issue