Merge branch 'develop' into bug/sc-15034

This commit is contained in:
Marcus Moore 2023-03-22 11:58:47 -07:00
commit f6d0dd0f93
No known key found for this signature in database
135 changed files with 2902 additions and 1678 deletions

View file

@ -2864,6 +2864,24 @@
"contributions": [
"code"
]
},
{
"login": "spencerrlongg",
"name": "Spencer Long",
"avatar_url": "https://avatars.githubusercontent.com/u/7305753?v=4",
"profile": "http://spencerlong.com",
"contributions": [
"code"
]
},
{
"login": "marcusmoore",
"name": "Marcus Moore",
"avatar_url": "https://avatars.githubusercontent.com/u/1141514?v=4",
"profile": "https://github.com/marcusmoore",
"contributions": [
"code"
]
}
]
}

View file

@ -36,7 +36,7 @@ jobs:
# Execute Codacy Analysis CLI and generate a SARIF output with the security issues identified during the analysis
- name: Run Codacy Analysis CLI
uses: codacy/codacy-analysis-cli-action@v4.2.0
uses: codacy/codacy-analysis-cli-action@v4.3.0
with:
# Check https://github.com/codacy/codacy-analysis-cli#project-token to get your project token from your Codacy repository
# You can also omit the token and run the tools that support default configurations

View file

@ -72,7 +72,7 @@ jobs:
# https://github.com/docker/build-push-action
- name: Build and push 'snipe-it' image
id: docker_build
uses: docker/build-push-action@v3
uses: docker/build-push-action@v4
with:
context: .
file: ./Dockerfile.alpine

View file

@ -72,7 +72,7 @@ jobs:
# https://github.com/docker/build-push-action
- name: Build and push 'snipe-it' image
id: docker_build
uses: docker/build-push-action@v3
uses: docker/build-push-action@v4
with:
context: .
file: ./Dockerfile

View file

@ -1,5 +1,5 @@
![Build Status](https://app.chipperci.com/projects/0e5f8979-31eb-4ee6-9abf-050b76ab0383/status/master) [![Crowdin](https://d322cqt584bo4o.cloudfront.net/snipe-it/localized.svg)](https://crowdin.com/project/snipe-it) [![Docker Pulls](https://img.shields.io/docker/pulls/snipe/snipe-it.svg)](https://hub.docker.com/r/snipe/snipe-it/) [![Twitter Follow](https://img.shields.io/twitter/follow/snipeitapp.svg?style=social)](https://twitter.com/snipeitapp) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/553ce52037fc43ea99149785afcfe641)](https://www.codacy.com/app/snipe/snipe-it?utm_source=github.com&utm_medium=referral&utm_content=snipe/snipe-it&utm_campaign=Badge_Grade)
[![All Contributors](https://img.shields.io/badge/all_contributors-315-orange.svg?style=flat-square)](#contributors) [![Discord](https://badgen.net/badge/icon/discord?icon=discord&label)](https://discord.gg/yZFtShAcKk) [![huntr](https://cdn.huntr.dev/huntr_security_badge_mono.svg)](https://huntr.dev)
[![All Contributors](https://img.shields.io/badge/all_contributors-317-orange.svg?style=flat-square)](#contributors) [![Discord](https://badgen.net/badge/icon/discord?icon=discord&label)](https://discord.gg/yZFtShAcKk) [![huntr](https://cdn.huntr.dev/huntr_security_badge_mono.svg)](https://huntr.dev)
## Snipe-IT - Open Source Asset Management System
@ -141,6 +141,7 @@ Thanks goes to all of these wonderful people ([emoji key](https://github.com/ken
| [<img src="https://avatars.githubusercontent.com/u/32363424?v=4" width="110px;"/><br /><sub>Peace</sub>](https://github.com/julian-piehl)<br />[💻](https://github.com/snipe/snipe-it/commits?author=julian-piehl "Code") | [<img src="https://avatars.githubusercontent.com/u/231528?v=4" width="110px;"/><br /><sub>Kyle Gordon</sub>](https://github.com/kylegordon)<br />[💻](https://github.com/snipe/snipe-it/commits?author=kylegordon "Code") | [<img src="https://avatars.githubusercontent.com/u/53009155?v=4" width="110px;"/><br /><sub>Katharina Drexel</sub>](http://www.bfh.ch)<br />[💻](https://github.com/snipe/snipe-it/commits?author=sunflowerbofh "Code") | [<img src="https://avatars.githubusercontent.com/u/1931963?v=4" width="110px;"/><br /><sub>David Sferruzza</sub>](https://david.sferruzza.fr/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=dsferruzza "Code") | [<img src="https://avatars.githubusercontent.com/u/19511639?v=4" width="110px;"/><br /><sub>Rick Nelson</sub>](https://github.com/rnelsonee)<br />[💻](https://github.com/snipe/snipe-it/commits?author=rnelsonee "Code") | [<img src="https://avatars.githubusercontent.com/u/94169344?v=4" width="110px;"/><br /><sub>BasO12</sub>](https://github.com/BasO12)<br />[💻](https://github.com/snipe/snipe-it/commits?author=BasO12 "Code") | [<img src="https://avatars.githubusercontent.com/u/111710123?v=4" width="110px;"/><br /><sub>Vautia</sub>](https://github.com/Vautia)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Vautia "Code") |
| [<img src="https://avatars.githubusercontent.com/u/28321?v=4" width="110px;"/><br /><sub>Chris Hartjes</sub>](http://www.littlehart.net/atthekeyboard)<br />[💻](https://github.com/snipe/snipe-it/commits?author=chartjes "Code") | [<img src="https://avatars.githubusercontent.com/u/2404584?v=4" width="110px;"/><br /><sub>geo-chen</sub>](https://github.com/geo-chen)<br />[💻](https://github.com/snipe/snipe-it/commits?author=geo-chen "Code") | [<img src="https://avatars.githubusercontent.com/u/6006620?v=4" width="110px;"/><br /><sub>Phan Nguyen</sub>](https://github.com/nh314)<br />[💻](https://github.com/snipe/snipe-it/commits?author=nh314 "Code") | [<img src="https://avatars.githubusercontent.com/u/115993812?v=4" width="110px;"/><br /><sub>Iisakki Jaakkola</sub>](https://github.com/StarlessNights)<br />[💻](https://github.com/snipe/snipe-it/commits?author=StarlessNights "Code") | [<img src="https://avatars.githubusercontent.com/u/22633385?v=4" width="110px;"/><br /><sub>Ikko Ashimine</sub>](https://bandism.net/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=eltociear "Code") | [<img src="https://avatars.githubusercontent.com/u/56871540?v=4" width="110px;"/><br /><sub>Lukas Fehling</sub>](https://github.com/lukasfehling)<br />[💻](https://github.com/snipe/snipe-it/commits?author=lukasfehling "Code") | [<img src="https://avatars.githubusercontent.com/u/1975990?v=4" width="110px;"/><br /><sub>Fernando Almeida</sub>](https://github.com/fernando-almeida)<br />[💻](https://github.com/snipe/snipe-it/commits?author=fernando-almeida "Code") |
| [<img src="https://avatars.githubusercontent.com/u/116301219?v=4" width="110px;"/><br /><sub>akemidx</sub>](https://github.com/akemidx)<br />[💻](https://github.com/snipe/snipe-it/commits?author=akemidx "Code") | [<img src="https://avatars.githubusercontent.com/u/144778?v=4" width="110px;"/><br /><sub>Oguz Bilgic</sub>](http://oguz.site)<br />[💻](https://github.com/snipe/snipe-it/commits?author=oguzbilgic "Code") | [<img src="https://avatars.githubusercontent.com/u/9262438?v=4" width="110px;"/><br /><sub>Scooter Crawford</sub>](https://github.com/scoo73r)<br />[💻](https://github.com/snipe/snipe-it/commits?author=scoo73r "Code") | [<img src="https://avatars.githubusercontent.com/u/5957345?v=4" width="110px;"/><br /><sub>subdriven</sub>](https://github.com/subdriven)<br />[💻](https://github.com/snipe/snipe-it/commits?author=subdriven "Code") | [<img src="https://avatars.githubusercontent.com/u/658865?v=4" width="110px;"/><br /><sub>Andrew Savinykh</sub>](https://github.com/AndrewSav)<br />[💻](https://github.com/snipe/snipe-it/commits?author=AndrewSav "Code") | [<img src="https://avatars.githubusercontent.com/u/1155067?v=4" width="110px;"/><br /><sub>Tadayuki Onishi</sub>](https://kenchan0130.github.io)<br />[💻](https://github.com/snipe/snipe-it/commits?author=kenchan0130 "Code") | [<img src="https://avatars.githubusercontent.com/u/112496896?v=4" width="110px;"/><br /><sub>Florian</sub>](https://github.com/floschoepfer)<br />[💻](https://github.com/snipe/snipe-it/commits?author=floschoepfer "Code") |
| [<img src="https://avatars.githubusercontent.com/u/7305753?v=4" width="110px;"/><br /><sub>Spencer Long</sub>](http://spencerlong.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=spencerrlongg "Code") | [<img src="https://avatars.githubusercontent.com/u/1141514?v=4" width="110px;"/><br /><sub>Marcus Moore</sub>](https://github.com/marcusmoore)<br />[💻](https://github.com/snipe/snipe-it/commits?author=marcusmoore "Code") |
<!-- ALL-CONTRIBUTORS-LIST:END -->
This project follows the [all-contributors](https://github.com/kentcdodds/all-contributors) specification. Contributions of any kind welcome!

View file

@ -0,0 +1,52 @@
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use App\Models\User;
class NormalizeUserNames extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'snipeit:normalize-names';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Normalizes weirdly formatted names as first-letter upercased';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return int
*/
public function handle()
{
$users = User::get();
$this->info($users->count() . ' users');
foreach ($users as $user) {
$user->first_name = ucwords(strtolower($user->first_name));
$user->last_name = ucwords(strtolower($user->last_name));
$user->email = strtolower($user->email);
$user->save();
}
}
}

24
app/Events/UserMerged.php Normal file
View file

@ -0,0 +1,24 @@
<?php
namespace App\Events;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
use App\Models\User;
class UserMerged
{
use Dispatchable, SerializesModels;
/**
* Create a new event instance.
*
* @return void
*/
public function __construct(User $from_user, User $to_user, User $admin)
{
$this->merged_from = $from_user;
$this->merged_to = $to_user;
$this->admin = $admin;
}
}

View file

@ -1092,6 +1092,15 @@ class Helper
return $file_name;
}
/**
* Universal helper to show file size in human-readable formats
*
* @author A. Gianotto <snipe@snipe.net>
* @since 5.0
*
* @return string[]
*/
public static function formatFilesizeUnits($bytes)
{
if ($bytes >= 1073741824)
@ -1121,30 +1130,91 @@ class Helper
return $bytes;
}
/**
* This is weird but used by the side nav to determine which URL to point the user to
*
* @author A. Gianotto <snipe@snipe.net>
* @since 5.0
*
* @return string[]
*/
public static function SettingUrls(){
$settings=['#','fields.index', 'statuslabels.index', 'models.index', 'categories.index', 'manufacturers.index', 'suppliers.index', 'departments.index', 'locations.index', 'companies.index', 'depreciations.index'];
return $settings;
}
public static function AgeFormat($date) {
$year = Carbon::parse($date)
->diff(now())->y;
$month = Carbon::parse($date)
->diff(now())->m;
$days = Carbon::parse($date)
->diff(now())->d;
$age='';
if ($year) {
$age .= $year.'y ';
}
if ($month) {
$age .= $month.'m ';
}
if ($days) {
$age .= $days.'d';
}
return $age;
/**
* Generic helper (largely used by livewire right now) that returns the font-awesome icon
* for the object type.
*
* @author A. Gianotto <snipe@snipe.net>
* @since 6.1.0
*
* @return string
*/
public static function iconTypeByItem($item) {
switch ($item) {
case 'asset':
return 'fas fa-barcode';
break;
case 'accessory':
return 'fas fa-keyboard';
break;
case 'component':
return 'fas fa-hdd';
break;
case 'consumable':
return 'fas fa-tint';
break;
case 'license':
return 'far fa-save';
break;
case 'location':
return 'fas fa-map-marker-alt';
break;
case 'user':
return 'fas fa-user';
break;
}
}
/*
* This is a shorter way to see if the app is in demo mode.
*
* This makes it cleanly available in blades and in controllers, e.g.
*
* Blade:
* {{ Helper::isDemoMode() ? ' disabled' : ''}} for form blades where we need to disable a form
*
* Controller:
* if (Helper::isDemoMode()) {
* // don't allow the thing
* }
* @todo - use this everywhere else in the app where we have very long if/else config('app.lock_passwords') stuff
*/
public static function isDemoMode() {
if (config('app.lock_passwords') === true) {
return true;
\Log::debug('app locked!');
}
return false;
}
/*
* I know it's gauche to return a shitty HTML string, but this is just a helper and since it will be the same every single time,
* it seemed pretty safe to do here. Don't you judge me.
*/
public static function showDemoModeFieldWarning() {
if (Helper::isDemoMode()) {
return "<p class=\"text-warning\"><i class=\"fas fa-lock\"></i>" . trans('general.feature_disabled') . "</p>";
}
}
}

View file

@ -115,6 +115,33 @@ class AccessoriesController extends Controller
}
/**
* Returns a view that presents a form to clone an accessory.
*
* @author [J. Vinsmoke]
* @param int $accessoryId
* @since [v6.0]
* @return View
*/
public function getClone($accessoryId = null)
{
$this->authorize('create', Accesory::class);
// Check if the asset exists
if (is_null($accessory_to_clone = Accessory::find($accessoryId))) {
// Redirect to the asset management page
return redirect()->route('accessory.index')->with('error', trans('admin/accessories/message.does_not_exist'));
}
$accessory = clone $accessory_to_clone;
$accessory->id = null;
$accessory->location_id = null;
return view('accessories/edit')
->with('item', $accessory);
}
/**
* Save edited Accessory from form post

View file

@ -941,18 +941,21 @@ class AssetsController extends Controller
* @since [v6.0]
* @return JsonResponse
*/
public function checkinByTag(Request $request)
public function checkinByTag(Request $request, $tag = null)
{
$this->authorize('checkin', Asset::class);
$asset = Asset::where('asset_tag', $request->input('asset_tag'))->first();
if(null == $tag && null !== ($request->input('asset_tag'))) {
$tag = $request->input('asset_tag');
}
$asset = Asset::where('asset_tag', $tag)->first();
if ($asset) {
return $this->checkin($request, $asset->id);
}
return response()->json(Helper::formatStandardApiResponse('error', [
'asset'=> e($request->input('asset_tag'))
], 'Asset with tag '.e($request->input('asset_tag')).' not found'));
'asset'=> e($tag)
], 'Asset with tag '.e($tag).' not found'));
}

View file

@ -8,6 +8,7 @@ use App\Http\Transformers\GroupsTransformer;
use App\Models\Group;
use Illuminate\Http\Request;
class GroupsController extends Controller
{
/**
@ -19,6 +20,8 @@ class GroupsController extends Controller
*/
public function index(Request $request)
{
$this->authorize('superadmin');
$this->authorize('view', Group::class);
$allowed_columns = ['id', 'name', 'created_at', 'users_count'];
@ -59,9 +62,11 @@ class GroupsController extends Controller
*/
public function store(Request $request)
{
$this->authorize('create', Group::class);
$this->authorize('superadmin');
$group = new Group;
$group->fill($request->all());
$group->name = $request->input('name');
$group->permissions = $request->input('permissions'); // Todo - some JSON validation stuff here
if ($group->save()) {
return response()->json(Helper::formatStandardApiResponse('success', $group, trans('admin/groups/message.create.success')));
@ -80,7 +85,7 @@ class GroupsController extends Controller
*/
public function show($id)
{
$this->authorize('view', Group::class);
$this->authorize('superadmin');
$group = Group::findOrFail($id);
return (new GroupsTransformer)->transformGroup($group);
@ -97,9 +102,11 @@ class GroupsController extends Controller
*/
public function update(Request $request, $id)
{
$this->authorize('update', Group::class);
$this->authorize('superadmin');
$group = Group::findOrFail($id);
$group->fill($request->all());
$group->name = $request->input('name');
$group->permissions = $request->input('permissions'); // Todo - some JSON validation stuff here
if ($group->save()) {
return response()->json(Helper::formatStandardApiResponse('success', $group, trans('admin/groups/message.update.success')));
@ -118,9 +125,8 @@ class GroupsController extends Controller
*/
public function destroy($id)
{
$this->authorize('delete', Group::class);
$this->authorize('superadmin');
$group = Group::findOrFail($id);
$this->authorize('delete', $group);
$group->delete();
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/groups/message.delete.success')));

View file

@ -10,7 +10,7 @@ use Illuminate\Support\Facades\Auth;
use Illuminate\Http\Request;
use Laravel\Passport\TokenRepository;
use Illuminate\Contracts\Validation\Factory as ValidationFactory;
use Gate;
use Illuminate\Support\Facades\Gate;
use DB;
class ProfileController extends Controller

View file

@ -20,6 +20,7 @@ use Auth;
use Illuminate\Http\Request;
use App\Http\Requests\ImageUploadRequest;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Validator;
class UsersController extends Controller
{
@ -191,7 +192,6 @@ class UsersController extends Controller
}
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
$offset = (($users) && (request('offset') > $users->count())) ? 0 : request('offset', 0);
// Set the offset to the API call's offset, unless the offset is higher than the actual count of items in which
// case we override with the actual count, so we should return 0 items.
@ -217,6 +217,14 @@ class UsersController extends Controller
case 'company':
$users = $users->OrderCompany($order);
break;
case 'first_name':
$users->orderBy('first_name', $order);
$users->orderBy('last_name', $order);
break;
case 'last_name':
$users->orderBy('last_name', $order);
$users->orderBy('first_name', $order);
break;
default:
$allowed_columns =
[
@ -457,6 +465,13 @@ class UsersController extends Controller
// Check if the request has groups passed and has a value
if ($request->filled('groups')) {
$validator = Validator::make($request->all(), [
'groups.*' => 'integer|exists:permission_groups,id',
]);
if ($validator->fails()){
return response()->json(Helper::formatStandardApiResponse('error', null, $user->getErrors()));
}
$user->groups()->sync($request->input('groups'));
// The groups field has been passed but it is null, so we should blank it out
} elseif ($request->has('groups')) {

View file

@ -16,7 +16,7 @@ use App\Models\User;
use Auth;
use Carbon\Carbon;
use DB;
use Gate;
use Illuminate\Support\Facades\Gate;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Storage;
@ -627,7 +627,11 @@ class AssetsController extends Controller
$csv->setHeaderOffset(0);
$header = $csv->getHeader();
$isCheckinHeaderExplicit = in_array('checkin date', (array_map('strtolower', $header)));
$results = $csv->getRecords();
try {
$results = $csv->getRecords();
} catch (\Exception $e) {
return back()->with('error', trans('general.error_in_import_file', ['error' => $e->getMessage()]));
}
$item = [];
$status = [];
$status['error'] = [];

View file

@ -102,8 +102,11 @@ class BulkAssetsController extends Controller
|| ($request->filled('company_id'))
|| ($request->filled('status_id'))
|| ($request->filled('model_id'))
|| ($request->filled('next_audit_date'))
|| ($request->filled('null_purchase_date'))
|| ($request->filled('null_expected_checkin_date'))
|| ($request->filled('null_next_audit_date'))
) {
foreach ($assets as $assetId) {
@ -116,7 +119,8 @@ class BulkAssetsController extends Controller
->conditionallyAddItem('requestable')
->conditionallyAddItem('status_id')
->conditionallyAddItem('supplier_id')
->conditionallyAddItem('warranty_months');
->conditionallyAddItem('warranty_months')
->conditionallyAddItem('next_audit_date');
if ($request->input('null_purchase_date')=='1') {
$this->update_array['purchase_date'] = null;
@ -126,6 +130,10 @@ class BulkAssetsController extends Controller
$this->update_array['expected_checkin'] = null;
}
if ($request->input('null_next_audit_date')=='1') {
$this->update_array['next_audit_date'] = null;
}
if ($request->filled('purchase_cost')) {
$this->update_array['purchase_cost'] = Helper::ParseCurrency($request->input('purchase_cost'));
}

View file

@ -1,22 +0,0 @@
<?php
namespace App\Http\Controllers;
use App\Http\Transformers\ImportsTransformer;
use App\Models\Asset;
use App\Models\Import;
class ImportsController extends Controller
{
/**
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function index()
{
$this->authorize('import');
$imports = (new ImportsTransformer)->transformImports(Import::latest()->get());
return view('importer/import')->with('imports', $imports);
}
}

View file

@ -91,29 +91,30 @@ class LicenseFilesController extends Controller
*/
public function destroy($licenseId = null, $fileId = null)
{
$license = License::find($licenseId);
if ($license = License::find($licenseId)) {
// the asset is valid
if (isset($license->id)) {
$this->authorize('update', $license);
$log = Actionlog::find($fileId);
// Remove the file if one exists
if (Storage::exists('licenses/'.$log->filename)) {
try {
Storage::delete('licenses/'.$log->filename);
} catch (\Exception $e) {
\Log::debug($e);
if ($log = Actionlog::find($fileId)) {
// Remove the file if one exists
if (Storage::exists('licenses/'.$log->filename)) {
try {
Storage::delete('licenses/'.$log->filename);
} catch (\Exception $e) {
\Log::debug($e);
}
}
$log->delete();
return redirect()->back()
->with('success', trans('admin/hardware/message.deletefile.success'));
}
$log->delete();
return redirect()->back()
->with('success', trans('admin/hardware/message.deletefile.success'));
return redirect()->route('licenses.index')->with('error', trans('general.log_does_not_exist'));
}
// Redirect to the licence management page
return redirect()->route('licenses.index')->with('error', trans('admin/licenses/message.does_not_exist'));
}
@ -129,7 +130,6 @@ class LicenseFilesController extends Controller
*/
public function show($licenseId = null, $fileId = null, $download = true)
{
\Log::info('Private filesystem is: '.config('filesystems.default'));
$license = License::find($licenseId);
// the license is valid

View file

@ -8,7 +8,7 @@ use App\Models\Setting;
use App\Models\User;
use App\Notifications\CurrentInventory;
use Illuminate\Support\Facades\Auth;
use Gate;
use Illuminate\Support\Facades\Gate;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Storage;

View file

@ -1024,7 +1024,11 @@ class ReportsController extends Controller
if (is_null($acceptance->created_at)){
return redirect()->route('reports/unaccepted_assets')->with('error', trans('general.bad_data'));
} else {
$logItem = $assetItem->checkouts()->where('created_at', '=', $acceptance->created_at)->get()[0];
$logItem_res = $assetItem->checkouts()->where('created_at', '=', $acceptance->created_at)->get();
if ($logItem_res->isEmpty()){
return redirect()->route('reports/unaccepted_assets')->with('error', trans('general.bad_data'));
}
$logItem = $logItem_res[0];
}
if(!$assetItem->assignedTo->locale){

View file

@ -2,6 +2,7 @@
namespace App\Http\Controllers\Users;
use App\Events\UserMerged;
use App\Helpers\Helper;
use App\Http\Controllers\Controller;
use App\Models\Accessory;
@ -13,6 +14,7 @@ use App\Models\LicenseSeat;
use App\Models\ConsumableAssignment;
use App\Models\Consumable;
use App\Models\User;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
@ -21,7 +23,7 @@ use Illuminate\Support\Facades\Password;
class BulkUsersController extends Controller
{
/**
* Returns a view that confirms the user's a bulk delete will be applied to.
* Returns a view that confirms the user's a bulk action will be applied to.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v1.7]
@ -35,16 +37,32 @@ class BulkUsersController extends Controller
// Make sure there were users selected
if (($request->filled('ids')) && (count($request->input('ids')) > 0)) {
// Get the list of affected users
$user_raw_array = request('ids');
$users = User::whereIn('id', $user_raw_array)
->with('groups', 'assets', 'licenses', 'accessories')->get();
// bulk edit, display the bulk edit form
if ($request->input('bulk_actions') == 'edit') {
return view('users/bulk-edit', compact('users'))
->with('groups', Group::pluck('name', 'id'));
// bulk delete, display the bulk delete confirmation form
} elseif ($request->input('bulk_actions') == 'delete') {
return view('users/confirm-bulk-delete')->with('users', $users)->with('statuslabel_list', Helper::statusLabelList());
// merge, confirm they have at least 2 users selected and display the merge screen
} elseif ($request->input('bulk_actions') == 'merge') {
if (($request->filled('ids')) && (count($request->input('ids')) > 1)) {
return view('users/confirm-merge')->with('users', $users);
// Not enough users selected, send them back
} else {
return redirect()->back()->with('error', trans('general.not_enough_users_selected', ['count' => 2]));
}
// bulk password reset, just do the thing
} elseif ($request->input('bulk_actions') == 'bulkpasswordreset') {
foreach ($users as $user) {
if (($user->activated == '1') && ($user->email != '')) {
@ -59,7 +77,7 @@ class BulkUsersController extends Controller
}
}
return redirect()->back()->with('error', 'No users selected');
return redirect()->back()->with('error', trans('general.no_users_selected'));
}
/**
@ -76,7 +94,7 @@ class BulkUsersController extends Controller
$this->authorize('update', User::class);
if ((! $request->filled('ids')) || $request->input('ids') <= 0) {
return redirect()->back()->with('error', 'No users selected');
return redirect()->back()->with('error', trans('general.no_users_selected'));
}
$user_raw_array = $request->input('ids');
@ -105,6 +123,11 @@ class BulkUsersController extends Controller
'warning' => trans('admin/users/message.bulk_manager_warn'),
];
}
if ($request->input('null_location_id')=='1') {
$this->update_array['location_id'] = null;
}
if (! $manager_conflict) {
$this->conditionallyAddItem('manager_id');
}
@ -163,11 +186,11 @@ class BulkUsersController extends Controller
$this->authorize('update', User::class);
if ((! $request->filled('ids')) || (count($request->input('ids')) == 0)) {
return redirect()->back()->with('error', 'No users selected');
return redirect()->back()->with('error', trans('general.no_users_selected'));
}
if (config('app.lock_passwords')) {
return redirect()->route('users.index')->with('error', 'Bulk delete is not enabled in this installation');
return redirect()->route('users.index')->with('error', trans('general.feature_disabled'));
}
$user_raw_array = request('ids');
@ -249,4 +272,80 @@ class BulkUsersController extends Controller
$logAction->logaction('checkin from');
}
}
/**
* Save bulk-edited users
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v1.0]
* @param Request $request
* @return \Illuminate\Http\RedirectResponse
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function merge(Request $request)
{
$this->authorize('update', User::class);
if (config('app.lock_passwords')) {
return redirect()->route('users.index')->with('error', trans('general.feature_disabled'));
}
$user_ids_to_merge = $request->input('ids_to_merge');
$user_ids_to_merge = array_diff($user_ids_to_merge, array($request->input('merge_into_id')));
if ((!$request->filled('merge_into_id')) || (count($user_ids_to_merge) < 1)) {
return redirect()->back()->with('error', trans('general.no_users_selected'));
}
// Get the users
$merge_into_user = User::find($request->input('merge_into_id'));
$users_to_merge = User::whereIn('id', $user_ids_to_merge)->with('assets', 'licenses', 'consumables','accessories')->get();
$admin = User::find(Auth::user()->id);
// Walk users
foreach ($users_to_merge as $user_to_merge) {
foreach ($user_to_merge->assets as $asset) {
\Log::debug('Updating asset: '.$asset->asset_tag . ' to '.$merge_into_user->id);
$asset->assigned_to = $request->input('merge_into_id');
$asset->save();
}
foreach ($user_to_merge->licenses as $license) {
\Log::debug('Updating license pivot: '.$license->id . ' to '.$merge_into_user->id);
$user_to_merge->licenses()->updateExistingPivot($license->id, ['assigned_to' => $merge_into_user->id]);
}
foreach ($user_to_merge->consumables as $consumable) {
\Log::debug('Updating consumable pivot: '.$consumable->id . ' to '.$merge_into_user->id);
$user_to_merge->consumables()->updateExistingPivot($consumable->id, ['assigned_to' => $merge_into_user->id]);
}
foreach ($user_to_merge->accessories as $accessory) {
$user_to_merge->accessories()->updateExistingPivot($accessory->id, ['assigned_to' => $merge_into_user->id]);
}
foreach ($user_to_merge->userlog as $log) {
$log->target_id = $user_to_merge->id;
$log->save();
}
User::where('manager_id', '=', $user_to_merge->id)->update(['manager_id' => $merge_into_user->id]);
foreach ($user_to_merge->managedLocations as $managedLocation) {
$managedLocation->manager_id = $merge_into_user->id;
$managedLocation->save();
}
$user_to_merge->delete();
//$user_to_merge->save();
event(new UserMerged($user_to_merge, $merge_into_user, $admin));
}
return redirect()->route('users.index')->with('success', trans('general.merge_success', ['count' => $users_to_merge->count(), 'into_username' => $merge_into_user->username]));
}
}

View file

@ -0,0 +1,322 @@
<?php
namespace App\Http\Livewire;
use App\Models\CustomField;
use Livewire\Component;
use App\Models\Import;
use Storage;
use Log;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
class Importer extends Component
{
use AuthorizesRequests;
public $files;
public $progress; //upload progress - '-1' means don't show
public $progress_message;
public $progress_bar_class;
public $message; //status/error message?
public $message_type; //success/error?
//originally from ImporterFile
public $import_errors; //
public ?Import $activeFile = null;
public $importTypes;
public $columnOptions;
public $statusType;
public $statusText;
public $update;
public $send_welcome;
public $run_backup;
public $field_map; // we need a separate variable for the field-mapping, because the keys in the normal array are too complicated for Livewire to understand
public $file_id; // TODO: I can't figure out *why* we need this, but it really seems like we do. I can't seem to pull the id from the activeFile for some reason?
protected $rules = [
'files.*.file_path' => 'required|string',
'files.*.created_at' => 'required|string',
'files.*.filesize' => 'required|integer',
'activeFile' => 'Import',
'activeFile.import_type' => 'string',
'activeFile.field_map' => 'array',
'activeFile.header_row' => 'array',
'field_map' => 'array'
];
public function generate_field_map()
{
\Log::debug("header row is: ".print_r($this->activeFile->header_row,true));
\Log::debug("Field map is: ".print_r($this->field_map,true));
$tmp = array_combine($this->activeFile->header_row, $this->field_map);
return json_encode(array_filter($tmp));
}
// all of these 'statics', alas, may have to change to something else to handle translations?
// I'm not sure. Maybe I use them to 'populate' the translations? TBH, I don't know yet.
static $general = [
'category' => 'Category',
'company' => 'Company',
'email' => 'Email',
'item_name' => 'Item Name',
'location' => 'Location',
'maintained' => 'Maintained',
'manufacturer' => 'Manufacturer',
'notes' => 'Notes',
'order_number' => 'Order Number',
'purchase_cost' => 'Purchase Cost',
'purchase_date' => 'Purchase Date',
'quantity' => 'Quantity',
'requestable' => 'Requestable',
'serial' => 'Serial Number',
'supplier' => 'Supplier',
'username' => 'Username',
'department' => 'Department',
];
static $accessories = [
'model_number' => 'Model Number',
];
static $assets = [
'asset_tag' => 'Asset Tag',
'asset_model' => 'Model Name',
'byod' => 'BYOD',
'checkout_class' => 'Checkout Type',
'checkout_location' => 'Checkout Location',
'image' => 'Image Filename',
'model_number' => 'Model Number',
'full_name' => 'Full Name',
'status' => 'Status',
'warranty_months' => 'Warranty Months',
];
static $consumables = [
'item_no' => "Item Number",
'model_number' => "Model Number",
'min_amt' => "Minimum Quantity",
];
static $licenses = [
'asset_tag' => 'Assigned To Asset',
'expiration_date' => 'Expiration Date',
'full_name' => 'Full Name',
'license_email' => 'Licensed To Email',
'license_name' => 'Licensed To Name',
'purchase_order' => 'Purchase Order',
'reassignable' => 'Reassignable',
'seats' => 'Seats',
];
static $users = [
'employee_num' => 'Employee Number',
'first_name' => 'First Name',
'jobtitle' => 'Job Title',
'last_name' => 'Last Name',
'phone_number' => 'Phone Number',
'manager_first_name' => 'Manager First Name',
'manager_last_name' => 'Manager Last Name',
'activated' => 'Activated',
'address' => 'Address',
'city' => 'City',
'state' => 'State',
'country' => 'Country',
'vip' => 'VIP'
];
//array of "real fieldnames" to a list of aliases for that field
static $aliases = [
'model_number' =>
[
'model',
'model no',
'model no.',
'model number',
'model num',
'model num.'
],
'warranty_months' =>
[
'Warranty',
'Warranty Months'
],
'qty' =>
[
'QTY',
'Quantity'
],
'min_amt' =>
[
'Min Amount',
'Min QTY'
],
'next_audit_date' =>
[
'Next Audit',
],
];
private function getColumns($type)
{
switch ($type) {
case 'asset':
$results = self::$general + self::$assets;
break;
case 'accessory':
$results = self::$general + self::$accessories;
break;
case 'consumable':
$results = self::$general + self::$consumables;
break;
case 'license':
$results = self::$general + self::$licenses;
break;
case 'user':
$results = self::$general + self::$users;
break;
default:
$results = self::$general;
}
asort($results, SORT_FLAG_CASE | SORT_STRING);
if ($type == "asset") {
// add Custom Fields after a horizontal line
$results['-'] = "———" . trans('admin/custom_fields/general.custom_fields') . "———’";
foreach (CustomField::orderBy('name')->get() as $field) {
$results[$field->db_column_name()] = $field->name;
}
}
return $results;
}
public function updating($name, $new_import_type)
{
if ($name == "activeFile.import_type") {
\Log::info("WE ARE CHANGING THE import_type!!!!! TO: " . $new_import_type);
\Log::info("so, what's \$this->>field_map at?: " . print_r($this->field_map, true));
// go through each header, find a matching field to try and map it to.
foreach ($this->activeFile->header_row as $i => $header) {
// do we have something mapped already?
if (array_key_exists($i, $this->field_map)) {
// yes, we do. Is it valid for this type of import?
// (e.g. the import type might have been changed...?)
if (array_key_exists($this->field_map[$i], $this->columnOptions[$new_import_type])) {
//yes, this key *is* valid. Continue on to the next field.
continue;
} else {
//no, this key is *INVALID* for this import type. Better set it to null
// and we'll hope that the aliases or something else picks it up.
$this->field_map[$i] = null; // fingers crossed! But it's not likely, tbh.
} // TODO - strictly speaking, this isn't necessary here I don't think.
}
// first, check for exact matches
foreach ($this->columnOptions[$new_import_type] as $value => $text) {
if (strcasecmp($text, $header) === 0) { // case-INSENSITIVe on purpose!
$this->field_map[$i] = $value;
continue 2; //don't bother with the alias check, go to the next header
}
}
// if you got here, we didn't find a match. Try the aliases
foreach (self::$aliases as $key => $alias_values) {
foreach ($alias_values as $alias_value) {
if (strcasecmp($alias_value, $header) === 0) { // aLsO CaSe-INSENSitiVE!
// Make *absolutely* sure that this key actually _exists_ in this import type -
// you can trigger this by importing accessories with a 'Warranty' column (which don't exist
// in "Accessories"!)
if (array_key_exists($key, $this->columnOptions[$new_import_type])) {
$this->field_map[$i] = $key;
continue 3; // bust out of both of these loops; as well as the surrounding one - e.g. move on to the next header
}
}
}
}
// and if you got here, we got nothing. Let's recommend 'null'
$this->field_map[$i] = null; // Booooo :(
}
}
}
public function boot() { // FIXME - delete or undelete.
///////$this->activeFile = null; // I do *not* understand why I have to do this, but, well, whatever.
}
public function mount()
{
$this->authorize('import');
$this->progress = -1; // '-1' means 'don't show the progressbar'
$this->progress_bar_class = 'progress-bar-warning';
\Log::info("Hey, we are calling MOUNT (in the importer-file) !!!!!!!!"); //fcuk
$this->importTypes = [
'asset' => trans('general.assets'),
'accessory' => trans('general.accessories'),
'consumable' => trans('general.consumables'),
'component' => trans('general.components'),
'license' => trans('general.licenses'),
'user' => trans('general.users'),
];
$this->columnOptions[''] = $this->getColumns(''); //blank mode? I don't know what this is supposed to mean
foreach($this->importTypes AS $type => $name) {
$this->columnOptions[$type] = $this->getColumns($type);
}
if ($this->activeFile) {
$this->field_map = $this->activeFile->field_map ? array_values($this->activeFile->field_map) : [];
}
}
public function selectFile($id)
{
\Log::info("TOGGLE EVENT FIRED!");
\Log::error("The ID we are trying to find is AS FOLLOWS: ".$id);
$this->activeFile = Import::find($id);
$this->field_map = null;
foreach($this->activeFile->header_row as $element) {
if(isset($this->activeFile->field_map[$element])) {
$this->field_map[] = $this->activeFile->field_map[$element];
} else {
$this->field_map[] = null; // re-inject the 'nulls' if a file was imported with some 'Do Not Import' settings
}
}
//$this->field_map = $this->activeFile->field_map ? array_values($this->activeFile->field_map) : []; // this is wrong
$this->file_id = $id;
$this->import_errors = null;
$this->statusText = null;
\Log::error("The import type we are about to try and load up is gonna be this: ".$this->activeFile->import_type);
}
public function destroy($id)
{
// TODO: why don't we just do File::find($id)? This seems dumb.
foreach($this->files as $file) {
\Log::debug("File id is: ".$file->id);
if($id == $file->id) {
if(Storage::delete('private_uploads/imports/'.$file->file_path)) {
$file->delete();
$this->message = trans('admin/hardware/message.import.file_delete_success');
$this->message_type = 'success';
return;
} else {
$this->message = trans('admin/hardware/message.import.file_delete_error');
$this->message_type = 'danger';
}
}
}
}
public function render()
{
$this->files = Import::orderBy('id','desc')->get(); //HACK - slows down renders.
return view('livewire.importer')
->extends('layouts.default')
->section('content');
}
}

View file

@ -5,50 +5,106 @@ namespace App\Http\Livewire;
use GuzzleHttp\Client;
use Livewire\Component;
use App\Models\Setting;
use App\Helpers\Helper;
class SlackSettingsForm extends Component
{
public $slack_endpoint;
public $slack_channel;
public $slack_botname;
public $isDisabled ='disabled' ;
public $webhook_endpoint;
public $webhook_channel;
public $webhook_botname;
public $isDisabled ='' ;
public $webhook_name;
public $webhook_link;
public $webhook_placeholder;
public $webhook_icon;
public $webhook_selected;
public array $webhook_text;
public Setting $setting;
protected $rules = [
'slack_endpoint' => 'url|required_with:slack_channel|starts_with:https://hooks.slack.com/|nullable',
'slack_channel' => 'required_with:slack_endpoint|starts_with:#|nullable',
'slack_botname' => 'string|nullable',
'webhook_endpoint' => 'url|required_with:webhook_channel|starts_with:https://hooks.slack.com/services|nullable',
'webhook_channel' => 'required_with:webhook_endpoint|starts_with:#|nullable',
'webhook_botname' => 'string|nullable',
];
public function mount(){
public function mount() {
$this->webhook_text= [
"slack" => array(
"name" => trans('admin/settings/general.slack') ,
"icon" => 'fab fa-slack',
"placeholder" => "https://hooks.slack.com/services/XXXXXXXXXXXXXXXXXXXXX",
"link" => 'https://api.slack.com/messaging/webhooks',
),
"general"=> array(
"name" => trans('admin/settings/general.general_webhook'),
"icon" => "fab fa-hashtag",
"placeholder" => "",
"link" => "",
),
];
$this->setting = Setting::getSettings();
$this->slack_endpoint = $this->setting->slack_endpoint;
$this->slack_channel = $this->setting->slack_channel;
$this->slack_botname = $this->setting->slack_botname;
$this->save_button = trans('general.save');
$this->webhook_selected = $this->setting->webhook_selected;
$this->webhook_placeholder = $this->webhook_text[$this->setting->webhook_selected]["placeholder"];
$this->webhook_name = $this->webhook_text[$this->setting->webhook_selected]["name"];
$this->webhook_icon = $this->webhook_text[$this->setting->webhook_selected]["icon"];
$this->webhook_endpoint = $this->setting->webhook_endpoint;
$this->webhook_channel = $this->setting->webhook_channel;
$this->webhook_botname = $this->setting->webhook_botname;
$this->webhook_options = $this->setting->webhook_selected;
if($this->setting->webhook_selected == 'general'){
$this->isDisabled='';
}
if($this->setting->webhook_endpoint != null && $this->setting->webhook_channel != null){
$this->isDisabled= '';
}
}
public function updated($field){
public function updated($field) {
if($this->webhook_selected != 'general') {
$this->validateOnly($field, $this->rules);
}
}
public function updatedWebhookSelected() {
$this->webhook_name = $this->webhook_text[$this->webhook_selected]['name'];
$this->webhook_icon = $this->webhook_text[$this->webhook_selected]["icon"]; ;
$this->webhook_placeholder = $this->webhook_text[$this->webhook_selected]["placeholder"];
$this->webhook_link = $this->webhook_text[$this->webhook_selected]["link"];
if($this->webhook_selected != 'slack'){
$this->isDisabled= '';
$this->save_button = trans('general.save');
}
}
private function isButtonDisabled() {
if($this->webhook_selected == 'slack') {
if (empty($this->webhook_endpoint)) {
$this->isDisabled = 'disabled';
$this->save_button = trans('admin/settings/general.webhook_presave');
}
if (empty($this->webhook_channel)) {
$this->isDisabled = 'disabled';
$this->save_button = trans('admin/settings/general.webhook_presave');
}
}
$this->validateOnly($field ,$this->rules);
}
public function render()
{
if(empty($this->slack_channel || $this->slack_endpoint)){
$this->isDisabled= 'disabled';
}
if(empty($this->slack_endpoint && $this->slack_channel)){
$this->isDisabled= '';
}
$this->isButtonDisabled();
return view('livewire.slack-settings-form');
}
public function testSlack(){
public function testWebhook(){
$slack = new Client([
'base_url' => e($this->slack_endpoint),
$webhook = new Client([
'base_url' => e($this->webhook_endpoint),
'defaults' => [
'exceptions' => false,
],
@ -56,40 +112,66 @@ class SlackSettingsForm extends Component
$payload = json_encode(
[
'channel' => e($this->slack_channel),
'text' => trans('general.slack_test_msg'),
'username' => e($this->slack_botname),
'channel' => e($this->webhook_channel),
'text' => trans('general.webhook_test_msg', ['app' => $this->webhook_name]),
'username' => e($this->webhook_botname),
'icon_emoji' => ':heart:',
]);
try {
$slack->post($this->slack_endpoint, ['body' => $payload]);
$webhook->post($this->webhook_endpoint, ['body' => $payload]);
$this->isDisabled='';
return session()->flash('success' , 'Your Slack Integration works!');
$this->save_button = trans('general.save');
return session()->flash('success' , 'Your '.$this->webhook_name.' Integration works!');
} catch (\Exception $e) {
$this->isDisabled= 'disabled';
return session()->flash('error' , trans('admin/settings/message.slack.error', ['error_message' => $e->getMessage()]));
return session()->flash('error' , trans('admin/settings/message.webhook.error', ['error_message' => $e->getMessage(), 'app' => $this->webhook_name]));
}
//}
return session()->flash('message' , trans('admin/settings/message.slack.error_misc'));
return session()->flash('error' , trans('admin/settings/message.webhook.error_misc'));
}
public function clearSettings(){
if (Helper::isDemoMode()) {
session()->flash('error',trans('general.feature_disabled'));
} else {
$this->webhook_endpoint = '';
$this->webhook_channel = '';
$this->webhook_botname = '';
$this->setting->webhook_endpoint = '';
$this->setting->webhook_channel = '';
$this->setting->webhook_botname = '';
$this->setting->save();
session()->flash('success', trans('admin/settings/message.update.success'));
}
}
public function submit()
{
$this->validate($this->rules);
if (Helper::isDemoMode()) {
session()->flash('error',trans('general.feature_disabled'));
} else {
if ($this->webhook_selected != 'general') {
$this->validate($this->rules);
}
$this->setting->slack_endpoint = $this->slack_endpoint;
$this->setting->slack_channel = $this->slack_channel;
$this->setting->slack_botname = $this->slack_botname;
$this->setting->webhook_selected = $this->webhook_selected;
$this->setting->webhook_endpoint = $this->webhook_endpoint;
$this->setting->webhook_channel = $this->webhook_channel;
$this->setting->webhook_botname = $this->webhook_botname;
$this->setting->save();
$this->setting->save();
session()->flash('save',trans('admin/settings/message.update.success'));
session()->flash('success',trans('admin/settings/message.update.success'));
}
}
}

View file

@ -3,7 +3,7 @@
namespace App\Http\Middleware;
use Closure;
use Gate;
use Illuminate\Support\Facades\Gate;
class CheckPermissions
{

View file

@ -4,7 +4,7 @@ namespace App\Http\Transformers;
use App\Helpers\Helper;
use App\Models\Accessory;
use Gate;
use Illuminate\Support\Facades\Gate;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Support\Facades\Storage;
@ -51,6 +51,8 @@ class AccessoriesTransformer
'checkin' => false,
'update' => Gate::allows('update', Accessory::class),
'delete' => Gate::allows('delete', Accessory::class),
'clone' => Gate::allows('create', Accessory::class),
];
$permissions_array['user_can_checkout'] = false;

View file

@ -5,7 +5,7 @@ namespace App\Http\Transformers;
use App\Helpers\Helper;
use App\Models\Asset;
use App\Models\AssetMaintenance;
use Gate;
use Illuminate\Support\Facades\Gate;
use Illuminate\Database\Eloquent\Collection;
class AssetMaintenancesTransformer
@ -45,6 +45,10 @@ class AssetMaintenancesTransformer
'name'=> e($assetmaintenance->asset->location->name),
] : null,
'rtd_location' => ($assetmaintenance->asset->defaultLoc) ? [
'id' => (int) $assetmaintenance->asset->defaultLoc->id,
'name'=> e($assetmaintenance->asset->defaultLoc->name),
] : null,
'notes' => ($assetmaintenance->notes) ? e($assetmaintenance->notes) : null,
'supplier' => ($assetmaintenance->supplier) ? ['id' => $assetmaintenance->supplier->id, 'name'=> e($assetmaintenance->supplier->name)] : null,
'cost' => Helper::formatCurrencyOutput($assetmaintenance->cost),

View file

@ -5,7 +5,7 @@ namespace App\Http\Transformers;
use App\Helpers\Helper;
use App\Models\Asset;
use App\Models\Setting;
use Gate;
use Illuminate\Support\Facades\Gate;
use Illuminate\Database\Eloquent\Collection;
@ -84,7 +84,7 @@ class AssetsTransformer
'next_audit_date' => Helper::getFormattedDateObject($asset->next_audit_date, 'date'),
'deleted_at' => Helper::getFormattedDateObject($asset->deleted_at, 'datetime'),
'purchase_date' => Helper::getFormattedDateObject($asset->purchase_date, 'date'),
'age' => $asset->purchase_date ? Helper::AgeFormat($asset->purchase_date) : '',
'age' => $asset->purchase_date ? $asset->purchase_date->diffForHumans() : '',
'last_checkout' => Helper::getFormattedDateObject($asset->last_checkout, 'datetime'),
'expected_checkin' => Helper::getFormattedDateObject($asset->expected_checkin, 'date'),
'purchase_cost' => Helper::formatCurrencyOutput($asset->purchase_cost),

View file

@ -4,7 +4,7 @@ namespace App\Http\Transformers;
use App\Helpers\Helper;
use App\Models\Category;
use Gate;
use Illuminate\Support\Facades\Gate;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Support\Facades\Storage;

View file

@ -4,7 +4,7 @@ namespace App\Http\Transformers;
use App\Helpers\Helper;
use App\Models\Company;
use Gate;
use Illuminate\Support\Facades\Gate;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Support\Facades\Storage;

View file

@ -3,7 +3,7 @@
namespace App\Http\Transformers;
use App\Models\Asset;
use Gate;
use Illuminate\Support\Facades\Gate;
use Illuminate\Database\Eloquent\Collection;
class ComponentsAssetsTransformer

View file

@ -4,7 +4,7 @@ namespace App\Http\Transformers;
use App\Helpers\Helper;
use App\Models\Component;
use Gate;
use Illuminate\Support\Facades\Gate;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Support\Facades\Storage;

View file

@ -4,7 +4,7 @@ namespace App\Http\Transformers;
use App\Helpers\Helper;
use App\Models\Consumable;
use Gate;
use Illuminate\Support\Facades\Gate;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Support\Facades\Storage;

View file

@ -4,7 +4,7 @@ namespace App\Http\Transformers;
use App\Helpers\Helper;
use App\Models\Department;
use Gate;
use Illuminate\Support\Facades\Gate;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Support\Facades\Storage;

View file

@ -5,7 +5,7 @@ namespace App\Http\Transformers;
use App\Helpers\Helper;
use App\Models\Depreciable;
use App\Models\Depreciation;
use Gate;
use Illuminate\Support\Facades\Gate;
use Illuminate\Database\Eloquent\Collection;
class DepreciationsTransformer

View file

@ -4,7 +4,7 @@ namespace App\Http\Transformers;
use App\Helpers\Helper;
use App\Models\Group;
use Gate;
use Illuminate\Support\Facades\Gate;
use Illuminate\Database\Eloquent\Collection;
class GroupsTransformer

View file

@ -4,7 +4,7 @@ namespace App\Http\Transformers;
use App\Models\License;
use App\Models\LicenseSeat;
use Gate;
use Illuminate\Support\Facades\Gate;
use Illuminate\Database\Eloquent\Collection;
class LicenseSeatsTransformer

View file

@ -4,7 +4,7 @@ namespace App\Http\Transformers;
use App\Helpers\Helper;
use App\Models\License;
use Gate;
use Illuminate\Support\Facades\Gate;
use Illuminate\Database\Eloquent\Collection;
class LicensesTransformer

View file

@ -4,7 +4,7 @@ namespace App\Http\Transformers;
use App\Helpers\Helper;
use App\Models\Manufacturer;
use Gate;
use Illuminate\Support\Facades\Gate;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Support\Facades\Storage;

View file

@ -4,7 +4,7 @@ namespace App\Http\Transformers;
use App\Models\PredefinedKit;
use App\Models\SnipeModel;
use Gate;
use Illuminate\Support\Facades\Gate;
use Illuminate\Database\Eloquent\Collection;
/**

View file

@ -4,7 +4,7 @@ namespace App\Http\Transformers;
use App\Helpers\Helper;
use App\Models\Statuslabel;
use Gate;
use Illuminate\Support\Facades\Gate;
use Illuminate\Database\Eloquent\Collection;
class StatuslabelsTransformer

View file

@ -4,7 +4,7 @@ namespace App\Http\Transformers;
use App\Helpers\Helper;
use App\Models\Supplier;
use Gate;
use Illuminate\Support\Facades\Gate;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Support\Facades\Storage;

View file

@ -4,7 +4,7 @@ namespace App\Http\Transformers;
use App\Helpers\Helper;
use App\Models\User;
use Gate;
use Illuminate\Support\Facades\Gate;
use Illuminate\Database\Eloquent\Collection;
class UsersTransformer

View file

@ -18,7 +18,9 @@ use App\Events\ItemDeclined;
use App\Events\LicenseCheckedIn;
use App\Events\LicenseCheckedOut;
use App\Models\Actionlog;
use App\Models\User;
use App\Models\LicenseSeat;
use App\Events\UserMerged;
class LogListener
{
@ -87,6 +89,43 @@ class LogListener
$logaction->save();
}
public function onUserMerged(UserMerged $event)
{
$to_from_array = [
'to_id' => $event->merged_to->id,
'to_username' => $event->merged_to->username,
'from_id' => $event->merged_from->id,
'from_username' => $event->merged_from->username,
];
// Add a record to the users being merged FROM
\Log::debug('Users merged: '.$event->merged_from->id .' ('.$event->merged_from->username.') merged into '. $event->merged_to->id. ' ('.$event->merged_to->username.')');
$logaction = new Actionlog();
$logaction->item_id = $event->merged_from->id;
$logaction->item_type = User::class;
$logaction->target_id = $event->merged_to->id;
$logaction->target_type = User::class;
$logaction->action_type = 'merged';
$logaction->note = trans('general.merged_log_this_user_from', $to_from_array);
$logaction->user_id = $event->admin->id;
$logaction->save();
// Add a record to the users being merged TO
$logaction = new Actionlog();
$logaction->target_id = $event->merged_from->id;
$logaction->target_type = User::class;
$logaction->item_id = $event->merged_to->id;
$logaction->item_type = User::class;
$logaction->action_type = 'merged';
$logaction->note = trans('general.merged_log_this_user_into', $to_from_array);
$logaction->user_id = $event->admin->id;
$logaction->save();
}
/**
* Register the listeners for the subscriber.
*
@ -99,6 +138,7 @@ class LogListener
'CheckoutableCheckedOut',
'CheckoutAccepted',
'CheckoutDeclined',
'UserMerged',
];
foreach ($list as $event) {
@ -108,4 +148,6 @@ class LogListener
);
}
}
}

View file

@ -238,7 +238,7 @@ class CustomField extends Model
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
* @return string
*/
public function db_column_name()
{

View file

@ -16,6 +16,11 @@ class Group extends SnipeModel
'name' => 'required|min:2|max:255',
];
protected $fillable = [
'name',
'permissions'
];
/**
* Whether the model should inject it's identifier to the unique
* validation rules before attempting validation. If this property

View file

@ -50,6 +50,8 @@ class ActionlogPresenter extends Presenter
return 'far fa-save';
} elseif ($this->itemType() == 'component') {
return 'far fa-hdd';
} elseif ($this->itemType() == 'user') {
return 'fa-solid fa-people-arrows';
}
}

View file

@ -39,7 +39,7 @@ class RouteServiceProvider extends ServiceProvider
{
Route::group([
'middleware' => 'web',
'namespace' => $this->namespace,
// 'namespace' => $this->namespace, //okay, I don't know what this means, but somehow this might be a problem for us?
], function ($router) {
require base_path('routes/web/hardware.php');
require base_path('routes/web/models.php');
@ -65,7 +65,7 @@ class RouteServiceProvider extends ServiceProvider
{
Route::group([
'middleware' => 'auth:api',
'namespace' => $this->namespace,
// 'namespace' => $this->namespace, // this might also be a problem? I don't really know :/
'prefix' => 'api',
], function ($router) {
require base_path('routes/api.php');

View file

@ -150,6 +150,7 @@ class SettingsServiceProvider extends ServiceProvider
// Set the monetary locale to the configured locale to make helper::parseFloat work.
setlocale(LC_MONETARY, config('app.locale'));
setlocale(LC_NUMERIC, config('app.locale'));
}
/**

View file

@ -127,6 +127,9 @@
"sort-packages": true,
"optimize-autoloader": true,
"discard-changes": true,
"process-timeout": 3000
"process-timeout": 3000,
"allow-plugins": {
"dealerdirect/phpcodesniffer-composer-installer": true
}
}
}

View file

@ -112,27 +112,31 @@ $config = [
'handler' => \Rollbar\Laravel\MonologHandler::class,
'access_token' => env('ROLLBAR_TOKEN'),
'level' => env('ROLLBAR_LEVEL', 'error'),
'check_ignore' => function($isUncaught, $args, $payload) {
if (App::environment('production') && is_object($args) && get_class($args) == Rollbar\ErrorWrapper::class && $args->errorLevel == E_WARNING ) {
\Log::info("IGNORING E_WARNING in production mode: ".$args->getMessage());
return true; // "TRUE - you should ignore it!"
}
$needle = "ArieTimmerman\\Laravel\\SCIMServer\\Exceptions\\SCIMException";
if (App::environment('production') && is_string($args) && strncmp($args, $needle, strlen($needle) ) === 0 ) {
\Log::info("String: '$args' looks like a SCIM Exception; ignoring error");
return true; //yes, *do* ignore it
}
return false;
},
],
],
];
// Only add rollbar if the .env has a rollbar token
if ((env('APP_ENV')=='production') && (env('ROLLBAR_TOKEN'))) {
// Only add rollbar if the .env has a rollbar token
$config['channels']['stack']['channels'] = ['single', 'rollbar'];
// and only add the rollbar filter under the same conditions
// Note: it will *not* be cacheable
$config['channels']['rollbar']['check_ignore'] = function ($isUncaught, $args, $payload) {
if (App::environment('production') && is_object($args) && get_class($args) == Rollbar\ErrorWrapper::class && $args->errorLevel == E_WARNING ) {
\Log::info("IGNORING E_WARNING in production mode: ".$args->getMessage());
return true; // "TRUE - you should ignore it!"
}
$needle = "ArieTimmerman\\Laravel\\SCIMServer\\Exceptions\\SCIMException";
if (App::environment('production') && is_string($args) && strncmp($args, $needle, strlen($needle) ) === 0 ) {
\Log::info("String: '$args' looks like a SCIM Exception; ignoring error");
return true; //yes, *do* ignore it
}
return false;
};
}

View file

@ -2,17 +2,14 @@
namespace Database\Factories;
use App\Models\Accessory;
use App\Models\Category;
use App\Models\Location;
use App\Models\Manufacturer;
use App\Models\Supplier;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
/*
|--------------------------------------------------------------------------
| Asset Model Factories
|--------------------------------------------------------------------------
|
| Factories related exclusively to creating models ..
|
*/
class AccessoryFactory extends Factory
{
/**
@ -20,7 +17,7 @@ class AccessoryFactory extends Factory
*
* @var string
*/
protected $model = \App\Models\Accessory::class;
protected $model = Accessory::class;
/**
* Define the model's default state.
@ -30,9 +27,16 @@ class AccessoryFactory extends Factory
public function definition()
{
return [
'user_id' => 1,
'name' => sprintf(
'%s %s',
$this->faker->randomElement(['Bluetooth', 'Wired']),
$this->faker->randomElement(['Keyboard', 'Wired'])
),
'user_id' => User::factory()->superuser(),
'category_id' => Category::factory(),
'model_number' => $this->faker->numberBetween(1000000, 50000000),
'location_id' => rand(1, 5),
'location_id' => Location::factory(),
'qty' => 1,
];
}
@ -42,11 +46,15 @@ class AccessoryFactory extends Factory
return [
'name' => 'Bluetooth Keyboard',
'image' => 'bluetooth.jpg',
'category_id' => 8,
'manufacturer_id' => 1,
'category_id' => function () {
return Category::where('name', 'Keyboards')->first() ?? Category::factory()->accessoryKeyboardCategory();
},
'manufacturer_id' => function () {
return Manufacturer::where('name', 'Apple')->first() ?? Manufacturer::factory()->apple();
},
'qty' => 10,
'min_amt' => 2,
'supplier_id' => rand(1, 5),
'supplier_id' => Supplier::factory(),
];
});
}
@ -57,11 +65,15 @@ class AccessoryFactory extends Factory
return [
'name' => 'USB Keyboard',
'image' => 'usb-keyboard.jpg',
'category_id' => 8,
'manufacturer_id' => 1,
'category_id' => function () {
return Category::where('name', 'Keyboards')->first() ?? Category::factory()->accessoryKeyboardCategory();
},
'manufacturer_id' => function () {
return Manufacturer::where('name', 'Apple')->first() ?? Manufacturer::factory()->apple();
},
'qty' => 15,
'min_amt' => 2,
'supplier_id' => rand(1, 5),
'supplier_id' => Supplier::factory(),
];
});
}
@ -72,11 +84,15 @@ class AccessoryFactory extends Factory
return [
'name' => 'Magic Mouse',
'image' => 'magic-mouse.jpg',
'category_id' => 9,
'manufacturer_id' => 1,
'category_id' => function () {
return Category::where('name', 'Mouse')->first() ?? Category::factory()->accessoryMouseCategory();
},
'manufacturer_id' => function () {
return Manufacturer::where('name', 'Apple')->first() ?? Manufacturer::factory()->apple();
},
'qty' => 13,
'min_amt' => 2,
'supplier_id' => rand(1, 5),
'supplier_id' => Supplier::factory(),
];
});
}
@ -87,8 +103,12 @@ class AccessoryFactory extends Factory
return [
'name' => 'Sculpt Comfort Mouse',
'image' => 'comfort-mouse.jpg',
'category_id' => 9,
'manufacturer_id' => 2,
'category_id' => function () {
return Category::where('name', 'Mouse')->first() ?? Category::factory()->accessoryMouseCategory();
},
'manufacturer_id' => function () {
return Manufacturer::where('name', 'Microsoft')->first() ?? Manufacturer::factory()->microsoft();
},
'qty' => 13,
'min_amt' => 2,
];

View file

@ -4,20 +4,12 @@ namespace Database\Factories;
use App\Models\Actionlog;
use App\Models\Asset;
use App\Models\Company;
use App\Models\License;
use App\Models\LicenseSeat;
use App\Models\Location;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
/*
|--------------------------------------------------------------------------
| Action Log Factories
|--------------------------------------------------------------------------
|
| This simulates checkin/checkout/etc activities
|
*/
class ActionlogFactory extends Factory
{
/**
@ -25,7 +17,7 @@ class ActionlogFactory extends Factory
*
* @var string
*/
protected $model = \App\Models\Actionlog::class;
protected $model = Actionlog::class;
/**
* Define the model's default state.
@ -34,71 +26,83 @@ class ActionlogFactory extends Factory
*/
public function definition()
{
$asset = \App\Models\Asset::factory()->create();
return [
'item_type' => get_class($asset),
'item_id' => 1,
'user_id' => 1,
'item_id' => Asset::factory(),
'item_type' => Asset::class,
'user_id' => User::factory()->superuser(),
'action_type' => 'uploaded',
];
}
public function assetCheckoutToUser()
{
return $this->state(function () {
$target = \App\Models\User::inRandomOrder()->first();
$item = \App\Models\Asset::RTD()->inRandomOrder()->first();
$user_id = rand(1, 2); // keep it simple - make it one of the two superadmins
$asset = Asset::where('id', $item->id)
->update(
$target = User::inRandomOrder()->first();
$asset = Asset::RTD()->inRandomOrder()->first();
$asset->update(
[
'assigned_to' => $target->id,
'assigned_type' => \App\Models\User::class,
'assigned_type' => User::class,
'location_id' => $target->location_id,
]
);
return [
'created_at' => $this->faker->dateTimeBetween('-1 years', 'now', date_default_timezone_get()),
'user_id' => $user_id,
'action_type' => 'checkout',
'item_id' => $item->id,
'item_type' => \App\Models\Asset::class,
'item_id' => $asset->id,
'item_type' => Asset::class,
'target_id' => $target->id,
'target_type' => get_class($target),
'target_type' => User::class,
];
});
}
public function assetCheckoutToLocation()
{
return $this->state(function () {
$target = \App\Models\Location::inRandomOrder()->first();
$item = \App\Models\Asset::inRandomOrder()->RTD()->first();
$user_id = rand(1, 2); // keep it simple - make it one of the two superadmins
$asset = \App\Models\Asset::where('id', $item->id)
->update(
$target = Location::inRandomOrder()->first();
$asset = Asset::inRandomOrder()->RTD()->first();
$asset->update(
[
'assigned_to' => $target->id,
'assigned_type' => \App\Models\Location::class,
'assigned_type' => Location::class,
'location_id' => $target->id,
]
);
return [
'created_at' => $this->faker->dateTimeBetween('-1 years', 'now', date_default_timezone_get()),
'user_id' => $user_id,
'action_type' => 'checkout',
'item_id' => $item->id,
'item_type' => \App\Models\Asset::class,
'item_id' => $asset->id,
'item_type' => Asset::class,
'target_id' => $target->id,
'target_type' => get_class($target),
'target_type' => Location::class,
];
});
}
public function licenseCheckoutToUser()
{
return $this->state(function () {
$target = User::inRandomOrder()->first();
$licenseSeat = LicenseSeat::whereNull('assigned_to')->inRandomOrder()->first();
$licenseSeat->update([
'assigned_to' => $target->id,
'user_id' => 1, // not ideal but works
]);
return [
'created_at' => $this->faker->dateTimeBetween('-1 years', 'now', date_default_timezone_get()),
'action_type' => 'checkout',
'item_id' => $licenseSeat->license->id,
'item_type' => License::class,
'target_id' => $target->id,
'target_type' => User::class,
];
});
}
}

View file

@ -4,22 +4,12 @@ namespace Database\Factories;
use App\Models\Asset;
use App\Models\AssetModel;
use App\Models\Category;
use App\Models\Location;
use App\Models\Statuslabel;
use App\Models\Supplier;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
/*
|--------------------------------------------------------------------------
| Model Factories
|--------------------------------------------------------------------------
|
| Factories related exclusively to modelling assets.
|
*/
// These are just for unit tests, not to generate data
class AssetFactory extends Factory
{
/**
@ -38,10 +28,13 @@ class AssetFactory extends Factory
{
return [
'name' => null,
'model_id' => AssetModel::factory(),
'rtd_location_id' => Location::factory(),
'serial' => $this->faker->uuid(),
'status_id' => 1,
'user_id' => 1,
'status_id' => function () {
return Statuslabel::where('name', 'Ready to Deploy')->first() ?? Statuslabel::factory()->rtd()->create(['name' => 'Ready to Deploy']);
},
'user_id' => User::factory()->superuser(),
'asset_tag' => $this->faker->unixTime('now'),
'notes' => 'Created by DB seeder',
'purchase_date' => $this->faker->dateTimeBetween('-1 years', 'now', date_default_timezone_get())->format('Y-m-d'),
@ -60,7 +53,9 @@ class AssetFactory extends Factory
{
return $this->state(function () {
return [
'model_id' => 1,
'model_id' => function () {
return AssetModel::where('name', 'Macbook Pro 13"')->first() ?? AssetModel::factory()->mbp13Model();
},
];
});
}
@ -69,8 +64,12 @@ class AssetFactory extends Factory
{
return $this->state(function () {
return [
'model_id' => 1,
'status_id' => 2,
'model_id' => function () {
return AssetModel::where('name', 'Macbook Pro 13"')->first() ?? AssetModel::factory()->mbp13Model();
},
'status_id' => function () {
return Statuslabel::where('name', 'Pending')->first() ?? Statuslabel::factory()->pending()->make(['name' => 'Pending']);
},
];
});
}
@ -79,8 +78,12 @@ class AssetFactory extends Factory
{
return $this->state(function () {
return [
'model_id' => 1,
'status_id' => 3,
'model_id' => function () {
return AssetModel::where('name', 'Macbook Pro 13"')->first() ?? AssetModel::factory()->mbp13Model();
},
'status_id' => function () {
return Statuslabel::where('name', 'Archived')->first() ?? Statuslabel::factory()->archived()->make(['name' => 'Archived']);
},
];
});
}
@ -89,7 +92,9 @@ class AssetFactory extends Factory
{
return $this->state(function () {
return [
'model_id' => 2,
'model_id' => function () {
return AssetModel::where('name', 'Macbook Air')->first() ?? AssetModel::factory()->mbpAirModel();
},
];
});
}
@ -98,7 +103,9 @@ class AssetFactory extends Factory
{
return $this->state(function () {
return [
'model_id' => 3,
'model_id' => function () {
return AssetModel::where('name', 'Surface')->first() ?? AssetModel::factory()->surfaceModel();
},
];
});
}
@ -107,7 +114,9 @@ class AssetFactory extends Factory
{
return $this->state(function () {
return [
'model_id' => 4,
'model_id' => function () {
return AssetModel::where('name', 'XPS 13')->first() ?? AssetModel::factory()->xps13Model();
},
];
});
}
@ -116,7 +125,9 @@ class AssetFactory extends Factory
{
return $this->state(function () {
return [
'model_id' => 5,
'model_id' => function () {
return AssetModel::where('name', 'Spectre')->first() ?? AssetModel::factory()->spectreModel();
},
];
});
}
@ -125,7 +136,9 @@ class AssetFactory extends Factory
{
return $this->state(function () {
return [
'model_id' => 6,
'model_id' => function () {
return AssetModel::where('name', 'ZenBook UX310')->first() ?? AssetModel::factory()->zenbookModel();
},
];
});
}
@ -134,7 +147,9 @@ class AssetFactory extends Factory
{
return $this->state(function () {
return [
'model_id' => 7,
'model_id' => function () {
return AssetModel::where('name', 'Yoga 910')->first() ?? AssetModel::factory()->yogaModel();
},
];
});
}
@ -143,7 +158,9 @@ class AssetFactory extends Factory
{
return $this->state(function () {
return [
'model_id' => 8,
'model_id' => function () {
return AssetModel::where('name', 'iMac Pro')->first() ?? AssetModel::factory()->macproModel();
},
];
});
}
@ -152,7 +169,9 @@ class AssetFactory extends Factory
{
return $this->state(function () {
return [
'model_id' => 9,
'model_id' => function () {
return AssetModel::where('name', 'Lenovo Intel Core i5')->first() ?? AssetModel::factory()->lenovoI5Model();
},
];
});
}
@ -161,7 +180,9 @@ class AssetFactory extends Factory
{
return $this->state(function () {
return [
'model_id' => 10,
'model_id' => function () {
return AssetModel::where('name', 'OptiPlex')->first() ?? AssetModel::factory()->optiplexModel();
},
];
});
}
@ -170,7 +191,9 @@ class AssetFactory extends Factory
{
return $this->state(function () {
return [
'model_id' => 11,
'model_id' => function () {
return AssetModel::where('name', 'SoundStation 2')->first() ?? AssetModel::factory()->polycomModel();
},
];
});
}
@ -179,7 +202,9 @@ class AssetFactory extends Factory
{
return $this->state(function () {
return [
'model_id' => 12,
'model_id' => function () {
return AssetModel::where('name', 'Polycom CX3000 IP Conference Phone')->first() ?? AssetModel::factory()->polycomcxModel();
},
];
});
}
@ -188,7 +213,9 @@ class AssetFactory extends Factory
{
return $this->state(function () {
return [
'model_id' => 13,
'model_id' => function () {
return AssetModel::where('name', 'iPad Pro')->first() ?? AssetModel::factory()->ipadModel();
},
];
});
}
@ -197,7 +224,9 @@ class AssetFactory extends Factory
{
return $this->state(function () {
return [
'model_id' => 14,
'model_id' => function () {
return AssetModel::where('name', 'Tab3')->first() ?? AssetModel::factory()->tab3Model();
},
];
});
}
@ -206,7 +235,9 @@ class AssetFactory extends Factory
{
return $this->state(function () {
return [
'model_id' => 15,
'model_id' => function () {
return AssetModel::where('name', 'iPhone 11')->first() ?? AssetModel::factory()->iphone11Model();
},
];
});
}
@ -215,7 +246,9 @@ class AssetFactory extends Factory
{
return $this->state(function () {
return [
'model_id' => 16,
'model_id' => function () {
return AssetModel::where('name', 'iPhone 12')->first() ?? AssetModel::factory()->iphone12Model();
},
];
});
}
@ -224,7 +257,9 @@ class AssetFactory extends Factory
{
return $this->state(function () {
return [
'model_id' => 17,
'model_id' => function () {
return AssetModel::where('name', 'Ultrafine 4k')->first() ?? AssetModel::factory()->ultrafine();
},
];
});
}
@ -233,7 +268,9 @@ class AssetFactory extends Factory
{
return $this->state(function () {
return [
'model_id' => 18,
'model_id' => function () {
return AssetModel::where('name', 'Ultrasharp U2415')->first() ?? AssetModel::factory()->ultrasharp();
},
];
});
}
@ -242,9 +279,8 @@ class AssetFactory extends Factory
{
return $this->state(function () {
return [
'model_id' => 1,
'assigned_to' => \App\Models\User::factory()->create()->id,
'assigned_type' => \App\Models\User::class,
'assigned_to' => User::factory(),
'assigned_type' => User::class,
];
});
}
@ -253,9 +289,8 @@ class AssetFactory extends Factory
{
return $this->state(function () {
return [
'model_id' => 1,
'assigned_to' => \App\Models\Location::factory()->create()->id,
'assigned_type' => \App\Models\Location::class,
'assigned_to' => Location::factory(),
'assigned_type' => Location::class,
];
});
}
@ -265,8 +300,8 @@ class AssetFactory extends Factory
return $this->state(function () {
return [
'model_id' => 1,
'assigned_to' => \App\Models\Asset::factory()->create()->id,
'assigned_type' => \App\Models\Asset::class,
'assigned_to' => Asset::factory(),
'assigned_type' => Asset::class,
];
});
}
@ -275,7 +310,9 @@ class AssetFactory extends Factory
{
return $this->state(function () {
return [
'model_id' => 1,
'model_id' => function () {
return AssetModel::where('name', 'Macbook Pro 13')->first() ?? AssetModel::factory()->mbp13Model();
},
];
});
}
@ -284,7 +321,9 @@ class AssetFactory extends Factory
{
return $this->state(function () {
return [
'model_id' => 1,
'model_id' => function () {
return AssetModel::where('name', 'Macbook Pro 13')->first() ?? AssetModel::factory()->mbp13Model();
},
'deleted_at' => $this->faker->dateTime(),
];
});

View file

@ -3,19 +3,10 @@
namespace Database\Factories;
use App\Models\Asset;
use App\Models\AssetModel;
use App\Models\Category;
use App\Models\AssetMaintenance;
use App\Models\Supplier;
use Illuminate\Database\Eloquent\Factories\Factory;
/*
|--------------------------------------------------------------------------
| Model Factories
|--------------------------------------------------------------------------
|
| Factories related exclusively to modelling assets.
|
*/
class AssetMaintenanceFactory extends Factory
{
/**
@ -23,7 +14,7 @@ class AssetMaintenanceFactory extends Factory
*
* @var string
*/
protected $model = \App\Models\AssetMaintenance::class;
protected $model = AssetMaintenance::class;
/**
* Define the model's default state.
@ -33,14 +24,10 @@ class AssetMaintenanceFactory extends Factory
public function definition()
{
return [
'asset_id' => function () {
return \App\Models\Asset::factory()->create()->id;
},
'supplier_id' => function () {
return \App\Models\Supplier::factory()->create()->id;
},
'asset_id' => Asset::factory(),
'supplier_id' => Supplier::factory(),
'asset_maintenance_type' => $this->faker->randomElement(['maintenance', 'repair', 'upgrade']),
'title' => $this->faker->sentence,
'title' => $this->faker->sentence(),
'start_date' => $this->faker->date(),
'is_warranty' => $this->faker->boolean(),
'notes' => $this->faker->paragraph(),

View file

@ -2,68 +2,14 @@
namespace Database\Factories;
use App\Models\AssetModel;
use App\Models\CustomFieldset;
use App\Models\Depreciation;
use App\Models\Manufacturer;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
use App\Models\Category;
/*
|--------------------------------------------------------------------------
| Asset Model Factories
|--------------------------------------------------------------------------
|
| Factories related exclusively to creating models ..
|
*/
/*
|--------------------------------------------------------------------------
| Laptops
|--------------------------------------------------------------------------
*/
// 1
// 2
// 3
// 4
// 5
// 6
// 7
/*
|--------------------------------------------------------------------------
| Desktops
|--------------------------------------------------------------------------
*/
/*
|--------------------------------------------------------------------------
| Conference Phones
|--------------------------------------------------------------------------
*/
/*
|--------------------------------------------------------------------------
| Tablets
|--------------------------------------------------------------------------
*/
/*
|--------------------------------------------------------------------------
| Mobile Phones
|--------------------------------------------------------------------------
*/
/*
|--------------------------------------------------------------------------
| Displays
|--------------------------------------------------------------------------
*/
class AssetModelFactory extends Factory
{
/**
@ -71,7 +17,7 @@ class AssetModelFactory extends Factory
*
* @var string
*/
protected $model = \App\Models\AssetModel::class;
protected $model = AssetModel::class;
/**
* Define the model's default state.
@ -81,8 +27,9 @@ class AssetModelFactory extends Factory
public function definition()
{
return [
'user_id' => 1,
'user_id' => User::factory()->superuser(),
'name' => $this->faker->catchPhrase(),
'category_id' => Category::factory(),
'model_number' => $this->faker->creditCardNumber(),
'notes' => 'Created by demo seeder',
@ -94,11 +41,17 @@ class AssetModelFactory extends Factory
return $this->state(function () {
return [
'name' => 'Macbook Pro 13"',
'category_id' => 1,
'category_id' => function () {
return Category::where('name', 'Laptops')->first() ?? Category::factory()->assetLaptopCategory();
},
'eol' => '36',
'depreciation_id' => 1,
'depreciation_id' => function () {
return Depreciation::where('name', 'Computer Depreciation')->first() ?? Depreciation::factory()->computer();
},
'image' => 'mbp.jpg',
'fieldset_id' => 2,
'fieldset_id' => function () {
return CustomFieldset::where('name', 'Laptops and Desktops')->first() ?? CustomFieldset::factory()->computer();
},
];
});
}
@ -108,12 +61,20 @@ class AssetModelFactory extends Factory
return $this->state(function () {
return [
'name' => 'Macbook Air',
'category_id' => 1,
'manufacturer_id' => 1,
'category_id' => function () {
return Category::where('name', 'Laptops')->first() ?? Category::factory()->assetLaptopCategory();
},
'manufacturer_id' => function () {
return Manufacturer::where('name', 'Apple')->first() ?? Manufacturer::factory()->apple();
},
'eol' => '36',
'depreciation_id' => 1,
'depreciation_id' => function () {
return Depreciation::where('name', 'Computer Depreciation')->first() ?? Depreciation::factory()->computer();
},
'image' => 'macbookair.jpg',
'fieldset_id' => 2,
'fieldset_id' => function () {
return CustomFieldset::where('name', 'Laptops and Desktops')->first() ?? CustomFieldset::factory()->computer();
},
];
});
}
@ -123,12 +84,20 @@ class AssetModelFactory extends Factory
return $this->state(function () {
return [
'name' => 'Surface',
'category_id' => 1,
'manufacturer_id' => 2,
'category_id' => function () {
return Category::where('name', 'Laptops')->first() ?? Category::factory()->assetLaptopCategory();
},
'manufacturer_id' => function () {
return Manufacturer::where('name', 'Microsoft')->first() ?? Manufacturer::factory()->microsoft();
},
'eol' => '36',
'depreciation_id' => 1,
'depreciation_id' => function () {
return Depreciation::where('name', 'Computer Depreciation')->first() ?? Depreciation::factory()->computer();
},
'image' => 'surface.jpg',
'fieldset_id' => 2,
'fieldset_id' => function () {
return CustomFieldset::where('name', 'Laptops and Desktops')->first() ?? CustomFieldset::factory()->computer();
},
];
});
}
@ -138,12 +107,20 @@ class AssetModelFactory extends Factory
return $this->state(function () {
return [
'name' => 'XPS 13',
'category_id' => 1,
'manufacturer_id' => 3,
'category_id' => function () {
return Category::where('name', 'Laptops')->first() ?? Category::factory()->assetLaptopCategory();
},
'manufacturer_id' => function () {
return Manufacturer::where('name', 'Dell')->first() ?? Manufacturer::factory()->dell();
},
'eol' => '36',
'depreciation_id' => 1,
'depreciation_id' => function () {
return Depreciation::where('name', 'Computer Depreciation')->first() ?? Depreciation::factory()->computer();
},
'image' => 'xps.jpg',
'fieldset_id' => 2,
'fieldset_id' => function () {
return CustomFieldset::where('name', 'Laptops and Desktops')->first() ?? CustomFieldset::factory()->computer();
},
];
});
}
@ -153,12 +130,20 @@ class AssetModelFactory extends Factory
return $this->state(function () {
return [
'name' => 'ZenBook UX310',
'category_id' => 1,
'manufacturer_id' => 4,
'category_id' => function () {
return Category::where('name', 'Laptops')->first() ?? Category::factory()->assetLaptopCategory();
},
'manufacturer_id' => function () {
return Manufacturer::where('name', 'Asus')->first() ?? Manufacturer::factory()->asus();
},
'eol' => '36',
'depreciation_id' => 1,
'depreciation_id' => function () {
return Depreciation::where('name', 'Computer Depreciation')->first() ?? Depreciation::factory()->computer();
},
'image' => 'zenbook.jpg',
'fieldset_id' => 2,
'fieldset_id' => function () {
return CustomFieldset::where('name', 'Laptops and Desktops')->first() ?? CustomFieldset::factory()->computer();
},
];
});
}
@ -168,12 +153,20 @@ class AssetModelFactory extends Factory
return $this->state(function () {
return [
'name' => 'Spectre',
'category_id' => 1,
'manufacturer_id' => 5,
'category_id' => function () {
return Category::where('name', 'Laptops')->first() ?? Category::factory()->assetLaptopCategory();
},
'manufacturer_id' => function () {
return Manufacturer::where('name', 'HP')->first() ?? Manufacturer::factory()->hp();
},
'eol' => '36',
'depreciation_id' => 1,
'depreciation_id' => function () {
return Depreciation::where('name', 'Computer Depreciation')->first() ?? Depreciation::factory()->computer();
},
'image' => 'spectre.jpg',
'fieldset_id' => 2,
'fieldset_id' => function () {
return CustomFieldset::where('name', 'Laptops and Desktops')->first() ?? CustomFieldset::factory()->computer();
},
];
});
}
@ -183,12 +176,20 @@ class AssetModelFactory extends Factory
return $this->state(function () {
return [
'name' => 'Yoga 910',
'category_id' => 1,
'manufacturer_id' => 6,
'category_id' => function () {
return Category::where('name', 'Laptops')->first() ?? Category::factory()->assetLaptopCategory();
},
'manufacturer_id' => function () {
return Manufacturer::where('name', 'Lenovo')->first() ?? Manufacturer::factory()->lenovo();
},
'eol' => '36',
'depreciation_id' => 1,
'depreciation_id' => function () {
return Depreciation::where('name', 'Computer Depreciation')->first() ?? Depreciation::factory()->computer();
},
'image' => 'yoga.png',
'fieldset_id' => 2,
'fieldset_id' => function () {
return CustomFieldset::where('name', 'Laptops and Desktops')->first() ?? CustomFieldset::factory()->computer();
},
];
});
}
@ -198,12 +199,20 @@ class AssetModelFactory extends Factory
return $this->state(function () {
return [
'name' => 'iMac Pro',
'category_id' => 2,
'manufacturer_id' => 1,
'category_id' => function (){
return Category::where('name', 'Desktops')->first() ?? Category::factory()->assetDesktopCategory();
},
'manufacturer_id' => function () {
return Manufacturer::where('name', 'Apple')->first() ?? Manufacturer::factory()->apple();
},
'eol' => '24',
'depreciation_id' => 1,
'depreciation_id' => function () {
return Depreciation::where('name', 'Computer Depreciation')->first() ?? Depreciation::factory()->computer();
},
'image' => 'imacpro.jpg',
'fieldset_id' => 2,
'fieldset_id' => function () {
return CustomFieldset::where('name', 'Laptops and Desktops')->first() ?? CustomFieldset::factory()->computer();
},
];
});
}
@ -213,12 +222,20 @@ class AssetModelFactory extends Factory
return $this->state(function () {
return [
'name' => 'Lenovo Intel Core i5',
'category_id' => 2,
'manufacturer_id' => 6,
'category_id' => function () {
return Category::where('name', 'Desktops')->first() ?? Category::factory()->assetDesktopCategory();
},
'manufacturer_id' => function () {
return Manufacturer::where('name', 'Lenovo')->first() ?? Manufacturer::factory()->lenovo();
},
'eol' => '24',
'depreciation_id' => 1,
'depreciation_id' => function () {
return Depreciation::where('name', 'Computer Depreciation')->first() ?? Depreciation::factory()->computer();
},
'image' => 'lenovoi5.png',
'fieldset_id' => 2,
'fieldset_id' => function () {
return CustomFieldset::where('name', 'Laptops and Desktops')->first() ?? CustomFieldset::factory()->computer();
},
];
});
}
@ -228,13 +245,21 @@ class AssetModelFactory extends Factory
return $this->state(function () {
return [
'name' => 'OptiPlex',
'category_id' => 2,
'manufacturer_id' => 3,
'category_id' => function (){
return Category::where('name', 'Desktops')->first() ?? Category::factory()->assetDesktopCategory();
},
'manufacturer_id' => function () {
return Manufacturer::where('name', 'Dell')->first() ?? Manufacturer::factory()->dell();
},
'model_number' => '5040 (MRR81)',
'eol' => '24',
'depreciation_id' => 1,
'depreciation_id' => function () {
return Depreciation::where('name', 'Computer Depreciation')->first() ?? Depreciation::factory()->computer();
},
'image' => 'optiplex.jpg',
'fieldset_id' => 2,
'fieldset_id' => function () {
return CustomFieldset::where('name', 'Laptops and Desktops')->first() ?? CustomFieldset::factory()->computer();
},
];
});
}
@ -244,10 +269,16 @@ class AssetModelFactory extends Factory
return $this->state(function () {
return [
'name' => 'SoundStation 2',
'category_id' => 6,
'manufacturer_id' => 8,
'category_id' => function () {
return Category::where('name', 'VOIP Phones')->first() ?? Category::factory()->assetVoipCategory();
},
'manufacturer_id' => function () {
return Manufacturer::where('name', 'Polycom')->first() ?? Manufacturer::factory()->polycom();
},
'eol' => '12',
'depreciation_id' => 1,
'depreciation_id' => function () {
return Depreciation::where('name', 'Computer Depreciation')->first() ?? Depreciation::factory()->computer();
},
'image' => 'soundstation.jpg',
];
});
@ -258,10 +289,16 @@ class AssetModelFactory extends Factory
return $this->state(function () {
return [
'name' => 'Polycom CX3000 IP Conference Phone',
'category_id' => 6,
'manufacturer_id' => 8,
'category_id' => function () {
return Category::where('name', 'VOIP Phones')->first() ?? Category::factory()->assetVoipCategory();
},
'manufacturer_id' => function () {
return Manufacturer::where('name', 'Polycom')->first() ?? Manufacturer::factory()->polycom();
},
'eol' => '12',
'depreciation_id' => 1,
'depreciation_id' => function () {
return Depreciation::where('name', 'Computer Depreciation')->first() ?? Depreciation::factory()->computer();
},
'image' => 'cx3000.png',
];
});
@ -272,10 +309,16 @@ class AssetModelFactory extends Factory
return $this->state(function () {
return [
'name' => 'iPad Pro',
'category_id' => 3,
'manufacturer_id' => 1,
'category_id' => function () {
return Category::where('name', 'Tablets')->first() ?? Category::factory()->assetTabletCategory();
},
'manufacturer_id' => function () {
return Manufacturer::where('name', 'Apple')->first() ?? Manufacturer::factory()->apple();
},
'eol' => '12',
'depreciation_id' => 1,
'depreciation_id' => function () {
return Depreciation::where('name', 'Computer Depreciation')->first() ?? Depreciation::factory()->computer();
},
'image' => 'ipad.jpg',
];
});
@ -286,10 +329,16 @@ class AssetModelFactory extends Factory
return $this->state(function () {
return [
'name' => 'Tab3',
'category_id' => 3,
'manufacturer_id' => 6,
'category_id' => function () {
return Category::where('name', 'Tablets')->first() ?? Category::factory()->assetTabletCategory();
},
'manufacturer_id' => function () {
return Manufacturer::where('name', 'Lenovo')->first() ?? Manufacturer::factory()->lenovo();
},
'eol' => '12',
'depreciation_id' => 1,
'depreciation_id' => function () {
return Depreciation::where('name', 'Computer Depreciation')->first() ?? Depreciation::factory()->computer();
},
'image' => 'tab3.png',
];
});
@ -300,12 +349,20 @@ class AssetModelFactory extends Factory
return $this->state(function () {
return [
'name' => 'iPhone 11',
'category_id' => 4,
'manufacturer_id' => 1,
'category_id' => function () {
return Category::where('name', 'Mobile Phones')->first() ?? Category::factory()->assetMobileCategory();
},
'manufacturer_id' => function () {
return Manufacturer::where('name', 'Apple')->first() ?? Manufacturer::factory()->apple();
},
'eol' => '12',
'depreciation_id' => 3,
'depreciation_id' => function () {
return Depreciation::where('name', 'Mobile Phone Depreciation')->first() ?? Depreciation::factory()->mobilePhones();
},
'image' => 'iphone11.jpeg',
'fieldset_id' => 1,
'fieldset_id' => function () {
return CustomFieldset::where('name', 'Mobile Devices')->first() ?? CustomFieldset::factory()->mobile();
},
];
});
}
@ -315,12 +372,20 @@ class AssetModelFactory extends Factory
return $this->state(function () {
return [
'name' => 'iPhone 12',
'category_id' => 4,
'manufacturer_id' => 1,
'category_id' => function () {
return Category::where('name', 'Mobile Phones')->first() ?? Category::factory()->assetMobileCategory();
},
'manufacturer_id' => function () {
return Manufacturer::where('name', 'Apple')->first() ?? Manufacturer::factory()->apple();
},
'eol' => '12',
'depreciation_id' => 1,
'depreciation_id' => function () {
return Depreciation::where('name', 'Computer Depreciation')->first() ?? Depreciation::factory()->computer();
},
'image' => 'iphone12.jpeg',
'fieldset_id' => 1,
'fieldset_id' => function () {
return CustomFieldset::where('name', 'Mobile Devices')->first() ?? CustomFieldset::factory()->mobile();
},
];
});
}
@ -330,10 +395,16 @@ class AssetModelFactory extends Factory
return $this->state(function () {
return [
'name' => 'Ultrafine 4k',
'category_id' => 5,
'manufacturer_id' => 7,
'category_id' => function () {
return Category::where('name', 'Displays')->first() ?? Category::factory()->assetDisplayCategory();
},
'manufacturer_id' => function () {
return Manufacturer::where('name', 'LG')->first() ?? Manufacturer::factory()->lg();
},
'eol' => '12',
'depreciation_id' => 2,
'depreciation_id' => function () {
return Depreciation::where('name', 'Display Depreciation')->first() ?? Depreciation::factory()->display();
},
'image' => 'ultrafine.jpg',
];
});
@ -344,10 +415,16 @@ class AssetModelFactory extends Factory
return $this->state(function () {
return [
'name' => 'Ultrasharp U2415',
'category_id' => 5,
'manufacturer_id' => 3,
'category_id' => function () {
return Category::where('name', 'Displays')->first() ?? Category::factory()->assetDisplayCategory();
},
'manufacturer_id' => function () {
return Manufacturer::where('name', 'Dell')->first() ?? Manufacturer::factory()->dell();
},
'eol' => '12',
'depreciation_id' => 2,
'depreciation_id' => function () {
return Depreciation::where('name', 'Display Depreciation')->first() ?? Depreciation::factory()->display();
},
'image' => 'ultrasharp.jpg',
];
});

View file

@ -2,18 +2,10 @@
namespace Database\Factories;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
use App\Models\Category;
/*
|--------------------------------------------------------------------------
| Category Factories
|--------------------------------------------------------------------------
|
| Factories related exclusively to creating categories and the various states..
|
*/
class CategoryFactory extends Factory
{
/**
@ -21,7 +13,7 @@ class CategoryFactory extends Factory
*
* @var string
*/
protected $model = \App\Models\Category::class;
protected $model = Category::class;
/**
* Define the model's default state.
@ -32,18 +24,19 @@ class CategoryFactory extends Factory
{
return [
'name' => $this->faker->catchPhrase(),
'category_type' => 'asset',
'checkin_email' => $this->faker->boolean(),
'eula_text' => $this->faker->paragraph(),
'require_acceptance' => false,
'use_default_eula' => $this->faker->boolean(),
'user_id' => 1,
'user_id' => User::factory()->superuser(),
];
}
// usage: Category::factory()->assetLaptopCategory();
public function assetLaptopCategory()
{
return Category::factory()->create([
return $this->state([
'name' => 'Laptops',
'category_type' => 'asset',
'require_acceptance' => true,
@ -53,7 +46,7 @@ class CategoryFactory extends Factory
// usage: Category::factory()->assetDesktopCategory();
public function assetDesktopCategory()
{
return Category::factory()->create([
return $this->state([
'name' => 'Desktops',
'category_type' => 'asset',
'require_acceptance' => true,
@ -63,7 +56,7 @@ class CategoryFactory extends Factory
// usage: Category::factory()->assetDisplayCategory();
public function assetDisplayCategory()
{
return Category::factory()->create([
return $this->state([
'name' => 'Displays',
'category_type' => 'asset',
]);
@ -72,7 +65,7 @@ class CategoryFactory extends Factory
// usage: Category::factory()->assetTabletCategory();
public function assetTabletCategory()
{
return Category::factory()->create([
return $this->state([
'name' => 'Tablets',
'category_type' => 'asset',
]);
@ -81,7 +74,7 @@ class CategoryFactory extends Factory
// usage: Category::factory()->assetMobileCategory();
public function assetMobileCategory()
{
return Category::factory()->create([
return $this->state([
'name' => 'Mobile Phones',
'category_type' => 'asset',
]);
@ -90,7 +83,7 @@ class CategoryFactory extends Factory
// usage: Category::factory()->assetConferenceCategory();
public function assetConferenceCategory()
{
return Category::factory()->create([
return $this->state([
'name' => 'Conference Phones',
'category_type' => 'asset',
]);
@ -100,7 +93,7 @@ class CategoryFactory extends Factory
// usage: Category::factory()->assetVoipCategory();
public function assetVoipCategory()
{
return Category::factory()->create([
return $this->state([
'name' => 'VOIP Phones',
'category_type' => 'asset',
]);
@ -109,8 +102,8 @@ class CategoryFactory extends Factory
// usage: Category::factory()->accessoryKeyboardCategory();
public function accessoryKeyboardCategory()
{
return Category::factory()->create([
'name' => 'Keyboardss',
return $this->state([
'name' => 'Keyboards',
'category_type' => 'accessory',
]);
}
@ -119,7 +112,7 @@ class CategoryFactory extends Factory
// usage: Category::factory()->accessoryMouseCategory();
public function accessoryMouseCategory()
{
return Category::factory()->create([
return $this->state([
'name' => 'Mouse',
'category_type' => 'accessory',
]);
@ -128,7 +121,7 @@ class CategoryFactory extends Factory
// usage: Category::factory()->componentHddCategory();
public function componentHddCategory()
{
return Category::factory()->create([
return $this->state([
'name' => 'HDD/SSD',
'category_type' => 'component',
]);
@ -137,7 +130,7 @@ class CategoryFactory extends Factory
// usage: Category::factory()->componentRamCategory();
public function componentRamCategory()
{
return Category::factory()->create([
return $this->state([
'name' => 'RAM',
'category_type' => 'component',
]);
@ -146,7 +139,7 @@ class CategoryFactory extends Factory
// usage: Category::factory()->consumablePaperCategory();
public function consumablePaperCategory()
{
return Category::factory()->create([
return $this->state([
'name' => 'Printer Paper',
'category_type' => 'consumable',
]);
@ -155,7 +148,7 @@ class CategoryFactory extends Factory
// usage: Category::factory()->consumableInkCategory();
public function consumableInkCategory()
{
return Category::factory()->create([
return $this->state([
'name' => 'Printer Ink',
'category_type' => 'consumable',
]);
@ -164,7 +157,7 @@ class CategoryFactory extends Factory
// usage: Category::factory()->licenseGraphicsCategory();
public function licenseGraphicsCategory()
{
return Category::factory()->create([
return $this->state([
'name' => 'Graphics Software',
'category_type' => 'license',
]);
@ -173,7 +166,7 @@ class CategoryFactory extends Factory
// usage: Category::factory()->licenseGraphicsCategory();
public function licenseOfficeCategory()
{
return Category::factory()->create([
return $this->state([
'name' => 'Office Software',
'category_type' => 'license',
]);

View file

@ -1,25 +1,8 @@
<?php
/*
|--------------------------------------------------------------------------
| Model Factories
|--------------------------------------------------------------------------
|
| Here you may define all of your model factories. Model factories give
| you a convenient way to create models for testing and seeding your
| database. Just tell the factory how a default model should look.
|
*/
namespace Database\Factories;
use App\Models\AssetModel;
use App\Models\Category;
use App\Models\Company;
use App\Models\Location;
use App\Models\Manufacturer;
use App\Models\Statuslabel;
use App\Models\Supplier;
use Illuminate\Database\Eloquent\Factories\Factory;
class CompanyFactory extends Factory
@ -29,7 +12,7 @@ class CompanyFactory extends Factory
*
* @var string
*/
protected $model = \App\Models\Company::class;
protected $model = Company::class;
/**
* Define the model's default state.
@ -39,7 +22,7 @@ class CompanyFactory extends Factory
public function definition()
{
return [
'name' => $this->faker->company,
'name' => $this->faker->company(),
];
}
}

View file

@ -2,17 +2,12 @@
namespace Database\Factories;
use App\Models\Category;
use App\Models\Company;
use App\Models\Component;
use App\Models\Location;
use Illuminate\Database\Eloquent\Factories\Factory;
/*
|--------------------------------------------------------------------------
| Components Factories
|--------------------------------------------------------------------------
|
| Factories related exclusively to creating components ..
|
*/
class ComponentFactory extends Factory
{
/**
@ -20,7 +15,7 @@ class ComponentFactory extends Factory
*
* @var string
*/
protected $model = \App\Models\Component::class;
protected $model = Component::class;
/**
* Define the model's default state.
@ -31,19 +26,15 @@ class ComponentFactory extends Factory
{
return [
'name' => $this->faker->text(20),
'category_id' => function () {
return \App\Models\Category::factory()->create()->id;
},
'location_id' => 1,
'serial' => $this->faker->uuid,
'category_id' => Category::factory(),
'location_id' => Location::factory(),
'serial' => $this->faker->uuid(),
'qty' => $this->faker->numberBetween(3, 10),
'order_number' => $this->faker->numberBetween(1000000, 50000000),
'purchase_date' => $this->faker->dateTime(),
'purchase_date' => $this->faker->dateTime()->format('Y-m-d'),
'purchase_cost' => $this->faker->randomFloat(2),
'min_amt' => $this->faker->numberBetween($min = 1, $max = 2),
'company_id' => function () {
return \App\Models\Company::factory()->create()->id;
},
'company_id' => Company::factory(),
];
}
@ -52,11 +43,12 @@ class ComponentFactory extends Factory
return $this->state(function () {
return [
'name' => 'Crucial 4GB DDR3L-1600 SODIMM',
'category_id' => 13,
'category_id' => function () {
return Category::where('name', 'RAM')->first() ?? Category::factory()->componentRamCategory();
},
'qty' => 10,
'min_amt' => 2,
'location_id' => 3,
'company_id' => 2,
'location_id' => Location::factory(),
];
});
}
@ -66,7 +58,9 @@ class ComponentFactory extends Factory
return $this->state(function () {
return [
'name' => 'Crucial 8GB DDR3L-1600 SODIMM Memory for Mac',
'category_id' => 13,
'category_id' => function () {
return Category::where('name', 'RAM')->first() ?? Category::factory()->componentRamCategory();
},
'qty' => 10,
'min_amt' => 2,
];
@ -78,7 +72,9 @@ class ComponentFactory extends Factory
return $this->state(function () {
return [
'name' => 'Crucial BX300 120GB SATA Internal SSD',
'category_id' => 12,
'category_id' => function () {
return Category::where('name', 'HDD/SSD')->first() ?? Category::factory()->componentHddCategory();
},
'qty' => 10,
'min_amt' => 2,
];
@ -90,7 +86,9 @@ class ComponentFactory extends Factory
return $this->state(function () {
return [
'name' => 'Crucial BX300 240GB SATA Internal SSD',
'category_id' => 12,
'category_id' => function () {
return Category::where('name', 'HDD/SSD')->first() ?? Category::factory()->componentHddCategory();
},
'qty' => 10,
'min_amt' => 2,
];

View file

@ -2,17 +2,13 @@
namespace Database\Factories;
use App\Models\Category;
use App\Models\Company;
use App\Models\Consumable;
use App\Models\Manufacturer;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
/*
|--------------------------------------------------------------------------
| Consumables Factories
|--------------------------------------------------------------------------
|
| Factories related exclusively to creating consumables ..
|
*/
class ConsumableFactory extends Factory
{
/**
@ -20,7 +16,7 @@ class ConsumableFactory extends Factory
*
* @var string
*/
protected $model = \App\Models\Consumable::class;
protected $model = Consumable::class;
/**
* Define the model's default state.
@ -30,13 +26,16 @@ class ConsumableFactory extends Factory
public function definition()
{
return [
'user_id' => 1,
'name' => $this->faker->word(),
'category_id' => Category::factory(),
'user_id' => User::factory()->superuser(),
'item_no' => $this->faker->numberBetween(1000000, 50000000),
'order_number' => $this->faker->numberBetween(1000000, 50000000),
'purchase_date' => $this->faker->dateTimeBetween('-1 years', 'now', date_default_timezone_get()),
'purchase_date' => $this->faker->dateTimeBetween('-1 years', 'now', date_default_timezone_get())->format('Y-m-d'),
'purchase_cost' => $this->faker->randomFloat(2, 1, 50),
'qty' => $this->faker->numberBetween(5, 10),
'min_amt' => $this->faker->numberBetween($min = 1, $max = 2),
'company_id' => Company::factory(),
];
}
@ -45,11 +44,14 @@ class ConsumableFactory extends Factory
return $this->state(function () {
return [
'name' => 'Cardstock (White)',
'category_id' => 10,
'manufacturer_id' => 10,
'category_id' => function () {
return Category::where('name', 'Printer Paper')->first() ?? Category::factory()->consumablePaperCategory();
},
'manufacturer_id' => function () {
return Manufacturer::where('name', 'Avery')->first() ?? Manufacturer::factory()->avery();
},
'qty' => 10,
'min_amt' => 2,
'company_id' => 3,
];
});
}
@ -59,8 +61,12 @@ class ConsumableFactory extends Factory
return $this->state(function () {
return [
'name' => 'Laserjet Paper (Ream)',
'category_id' => 10,
'manufacturer_id' => 10,
'category_id' => function () {
return Category::where('name', 'Printer Paper')->first() ?? Category::factory()->consumablePaperCategory();
},
'manufacturer_id' => function () {
return Manufacturer::where('name', 'Avery')->first() ?? Manufacturer::factory()->avery();
},
'qty' => 20,
'min_amt' => 2,
];
@ -72,8 +78,12 @@ class ConsumableFactory extends Factory
return $this->state(function () {
return [
'name' => 'Laserjet Toner (black)',
'category_id' => 11,
'manufacturer_id' => 5,
'category_id' => function () {
return Category::where('name', 'Printer Ink')->first() ?? Category::factory()->consumableInkCategory();
},
'manufacturer_id' => function () {
return Manufacturer::where('name', 'HP')->first() ?? Manufacturer::factory()->hp();
},
'qty' => 20,
'min_amt' => 2,
];

View file

@ -2,6 +2,7 @@
namespace Database\Factories;
use App\Models\CustomField;
use Illuminate\Database\Eloquent\Factories\Factory;
class CustomFieldFactory extends Factory
@ -11,7 +12,7 @@ class CustomFieldFactory extends Factory
*
* @var string
*/
protected $model = \App\Models\CustomField::class;
protected $model = CustomField::class;
/**
* Define the model's default state.
@ -21,7 +22,7 @@ class CustomFieldFactory extends Factory
public function definition()
{
return [
'name' => $this->faker->catchPhrase,
'name' => $this->faker->catchPhrase(),
'format' => '',
'element' => 'text',
];

View file

@ -2,6 +2,7 @@
namespace Database\Factories;
use App\Models\CustomFieldset;
use Illuminate\Database\Eloquent\Factories\Factory;
class CustomFieldsetFactory extends Factory
@ -11,7 +12,7 @@ class CustomFieldsetFactory extends Factory
*
* @var string
*/
protected $model = \App\Models\CustomFieldset::class;
protected $model = CustomFieldset::class;
/**
* Define the model's default state.
@ -21,7 +22,7 @@ class CustomFieldsetFactory extends Factory
public function definition()
{
return [
'name' => $this->faker->catchPhrase,
'name' => $this->faker->catchPhrase(),
];
}

View file

@ -2,17 +2,11 @@
namespace Database\Factories;
use App\Models\Department;
use App\Models\Location;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
/*
|--------------------------------------------------------------------------
| Asset Model Factories
|--------------------------------------------------------------------------
|
| Factories related exclusively to creating models ..
|
*/
class DepartmentFactory extends Factory
{
/**
@ -20,7 +14,7 @@ class DepartmentFactory extends Factory
*
* @var string
*/
protected $model = \App\Models\Department::class;
protected $model = Department::class;
/**
* Define the model's default state.
@ -30,8 +24,9 @@ class DepartmentFactory extends Factory
public function definition()
{
return [
'user_id' => 1,
'location_id' => rand(1, 5),
'name' => $this->faker->word() . ' Department',
'user_id' => User::factory()->superuser(),
'location_id' => Location::factory(),
];
}

View file

@ -2,17 +2,10 @@
namespace Database\Factories;
use App\Models\Depreciation;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
/*
|--------------------------------------------------------------------------
| Asset Model Factories
|--------------------------------------------------------------------------
|
| Factories related exclusively to creating models ..
|
*/
class DepreciationFactory extends Factory
{
/**
@ -20,7 +13,7 @@ class DepreciationFactory extends Factory
*
* @var string
*/
protected $model = \App\Models\Depreciation::class;
protected $model = Depreciation::class;
/**
* Define the model's default state.
@ -31,7 +24,7 @@ class DepreciationFactory extends Factory
{
return [
'name' => $this->faker->catchPhrase(),
'user_id' => 1,
'user_id' => User::factory()->superuser(),
'months' => 36,
];
}

View file

@ -1,25 +1,8 @@
<?php
/*
|--------------------------------------------------------------------------
| Model Factories
|--------------------------------------------------------------------------
|
| Here you may define all of your model factories. Model factories give
| you a convenient way to create models for testing and seeding your
| database. Just tell the factory how a default model should look.
|
*/
namespace Database\Factories;
use App\Models\AssetModel;
use App\Models\Category;
use App\Models\Company;
use App\Models\Location;
use App\Models\Manufacturer;
use App\Models\Statuslabel;
use App\Models\Supplier;
use App\Models\Group;
use Illuminate\Database\Eloquent\Factories\Factory;
class GroupFactory extends Factory
@ -29,7 +12,7 @@ class GroupFactory extends Factory
*
* @var string
*/
protected $model = \App\Models\Group::class;
protected $model = Group::class;
/**
* Define the model's default state.
@ -39,7 +22,7 @@ class GroupFactory extends Factory
public function definition()
{
return [
'name' => $this->faker->name,
'name' => $this->faker->name(),
];
}
}

View file

@ -2,25 +2,12 @@
namespace Database\Factories;
use App\Models\Category;
use App\Models\License;
use App\Models\Manufacturer;
use App\Models\Supplier;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
/*
|--------------------------------------------------------------------------
| Asset Model Factories
|--------------------------------------------------------------------------
|
| Factories related exclusively to creating models ..
|
*/
// 1
// 2
// 3
// 4
class LicenseFactory extends Factory
{
/**
@ -28,7 +15,7 @@ class LicenseFactory extends Factory
*
* @var string
*/
protected $model = \App\Models\License::class;
protected $model = License::class;
/**
* Define the model's default state.
@ -37,13 +24,11 @@ class LicenseFactory extends Factory
*/
public function definition()
{
return [
'user_id' => 1,
'name' => $this->faker->name,
'license_email' => $this->faker->safeEmail,
'serial' => $this->faker->uuid,
'user_id' => User::factory()->superuser(),
'name' => $this->faker->name(),
'license_email' => $this->faker->safeEmail(),
'serial' => $this->faker->uuid(),
'notes' => 'Created by DB seeder',
'seats' => $this->faker->numberBetween(1, 10),
'purchase_date' => $this->faker->dateTimeBetween('-1 years', 'now', date_default_timezone_get())->format('Y-m-d'),
@ -51,8 +36,8 @@ class LicenseFactory extends Factory
'expiration_date' => $this->faker->dateTimeBetween('now', '+3 years', date_default_timezone_get())->format('Y-m-d H:i:s'),
'reassignable' => $this->faker->boolean(),
'termination_date' => $this->faker->dateTimeBetween('-1 years', 'now', date_default_timezone_get())->format('Y-m-d H:i:s'),
'supplier_id' => $this->faker->numberBetween(1, 5),
'category_id' => Category::where('category_type', '=', 'license')->inRandomOrder()->first()->id
'supplier_id' => Supplier::factory(),
'category_id' => Category::factory(),
];
}
@ -61,12 +46,16 @@ class LicenseFactory extends Factory
return $this->state(function () {
$data = [
'name' => 'Photoshop',
'manufacturer_id' => 9,
'manufacturer_id' => function () {
return Manufacturer::where('name', 'Adobe')->first() ?? Manufacturer::factory()->adobe();
},
'purchase_cost' => '299.99',
'seats' => 10,
'purchase_order' => '13503Q',
'maintained' => true,
'category_id' => 14,
'category_id' => function () {
return Category::where('name', 'Graphics Software')->first() ?? Category::factory()->licenseGraphicsCategory();
},
];
return $data;
@ -78,10 +67,14 @@ class LicenseFactory extends Factory
return $this->state(function () {
$data = [
'name' => 'Acrobat',
'manufacturer_id' => 9,
'manufacturer_id' => function () {
return Manufacturer::where('name', 'Adobe')->first() ?? Manufacturer::factory()->adobe();
},
'purchase_cost' => '29.99',
'seats' => 10,
'category_id' => 14,
'category_id' => function () {
return Category::where('name', 'Graphics Software')->first() ?? Category::factory()->licenseGraphicsCategory();
},
];
return $data;
@ -93,10 +86,14 @@ class LicenseFactory extends Factory
return $this->state(function () {
$data = [
'name' => 'InDesign',
'manufacturer_id' => 9,
'manufacturer_id' => function () {
return Manufacturer::where('name', 'Adobe')->first() ?? Manufacturer::factory()->adobe();
},
'purchase_cost' => '199.99',
'seats' => 10,
'category_id' => 14,
'category_id' => function () {
return Category::where('name', 'Graphics Software')->first() ?? Category::factory()->licenseGraphicsCategory();
},
];
@ -109,10 +106,14 @@ class LicenseFactory extends Factory
return $this->state(function () {
$data = [
'name' => 'Office',
'manufacturer_id' => 2,
'manufacturer_id' => function () {
return Manufacturer::where('name', 'Microsoft')->first() ?? Manufacturer::factory()->microsoft();
},
'purchase_cost' => '49.99',
'seats' => 20,
'category_id' => 15,
'category_id' => function () {
return Category::where('name', 'Office Software')->first() ?? Category::factory()->licenseOfficeCategory();
},
];
return $data;

View file

@ -23,8 +23,6 @@ class LocationFactory extends Factory
'currency' => $this->faker->currencyCode(),
'zip' => $this->faker->postcode(),
'image' => rand(1, 9).'.jpg',
];
}
}

View file

@ -2,39 +2,10 @@
namespace Database\Factories;
use App\Models\Manufacturer;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
/*
|--------------------------------------------------------------------------
| Asset Model Factories
|--------------------------------------------------------------------------
|
| Factories related exclusively to creating models ..
|
*/
// 1
// 2
// 3
// 4
// 5
// 6
// 7
// 8
// 9
// 10
// 11
class ManufacturerFactory extends Factory
{
/**
@ -42,7 +13,7 @@ class ManufacturerFactory extends Factory
*
* @var string
*/
protected $model = \App\Models\Manufacturer::class;
protected $model = Manufacturer::class;
/**
* Define the model's default state.
@ -52,7 +23,8 @@ class ManufacturerFactory extends Factory
public function definition()
{
return [
'user_id' => 1,
'name' => $this->faker->company(),
'user_id' => User::factory()->superuser(),
'support_phone' => $this->faker->phoneNumber(),
'url' => $this->faker->url(),
'support_email' => $this->faker->safeEmail(),

View file

@ -1,25 +1,8 @@
<?php
/*
|--------------------------------------------------------------------------
| Model Factories
|--------------------------------------------------------------------------
|
| Here you may define all of your model factories. Model factories give
| you a convenient way to create models for testing and seeding your
| database. Just tell the factory how a default model should look.
|
*/
namespace Database\Factories;
use App\Models\AssetModel;
use App\Models\Category;
use App\Models\Company;
use App\Models\Location;
use App\Models\Manufacturer;
use App\Models\Statuslabel;
use App\Models\Supplier;
use App\Models\Setting;
use Illuminate\Database\Eloquent\Factories\Factory;
class SettingFactory extends Factory
@ -29,7 +12,7 @@ class SettingFactory extends Factory
*
* @var string
*/
protected $model = \App\Models\Setting::class;
protected $model = Setting::class;
/**
* Define the model's default state.
@ -39,14 +22,13 @@ class SettingFactory extends Factory
public function definition()
{
return [
'user_id' => 1,
'per_page' => 20,
'site_name' => $this->faker->sentence,
'site_name' => $this->faker->sentence(),
'auto_increment_assets' => false,
'alert_email' => $this->faker->safeEmail(),
'alerts_enabled' => true,
'brand' => 1,
'default_currency' => $this->faker->currencyCode,
'default_currency' => $this->faker->currencyCode(),
'locale' => 'en',
'pwd_secure_min' => 10, // Match web setup
'email_domain' => 'test.com',

View file

@ -3,6 +3,7 @@
namespace Database\Factories;
use App\Models\Statuslabel;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
class StatuslabelFactory extends Factory
@ -22,10 +23,10 @@ class StatuslabelFactory extends Factory
public function definition()
{
return [
'name' => $this->faker->sentence,
'name' => $this->faker->sentence(),
'created_at' => $this->faker->dateTime(),
'updated_at' => $this->faker->dateTime(),
'user_id' => 1,
'user_id' => User::factory()->superuser(),
'deleted_at' => null,
'deployable' => 0,
'pending' => 0,
@ -38,7 +39,7 @@ class StatuslabelFactory extends Factory
{
return $this->state(function () {
return [
'notes' => $this->faker->sentence,
'notes' => $this->faker->sentence(),
'deployable' => 1,
'default_label' => 1,
];
@ -49,7 +50,7 @@ class StatuslabelFactory extends Factory
{
return $this->state(function () {
return [
'notes' => $this->faker->sentence,
'notes' => $this->faker->sentence(),
'pending' => 1,
'default_label' => 1,
];

View file

@ -1,24 +1,7 @@
<?php
/*
|--------------------------------------------------------------------------
| Model Factories
|--------------------------------------------------------------------------
|
| Here you may define all of your model factories. Model factories give
| you a convenient way to create models for testing and seeding your
| database. Just tell the factory how a default model should look.
|
*/
namespace Database\Factories;
use App\Models\AssetModel;
use App\Models\Category;
use App\Models\Company;
use App\Models\Location;
use App\Models\Manufacturer;
use App\Models\Statuslabel;
use App\Models\Supplier;
use Illuminate\Database\Eloquent\Factories\Factory;
@ -29,7 +12,7 @@ class SupplierFactory extends Factory
*
* @var string
*/
protected $model = \App\Models\Supplier::class;
protected $model = Supplier::class;
/**
* Define the model's default state.

View file

@ -2,6 +2,8 @@
namespace Database\Factories;
use App\Models\Company;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
use \Auth;
@ -18,10 +20,9 @@ class UserFactory extends Factory
'activated' => 1,
'address' => $this->faker->address(),
'city' => $this->faker->city(),
'company_id' => rand(1, 4),
'company_id' => Company::factory(),
'country' => $this->faker->country(),
'department_id' => rand(1, 6),
'email' => $this->faker->safeEmail,
'email' => $this->faker->safeEmail(),
'employee_num' => $this->faker->numberBetween(3500, 35050),
'first_name' => $this->faker->firstName(),
'jobtitle' => $this->faker->jobTitle(),
@ -30,10 +31,10 @@ class UserFactory extends Factory
'notes' => 'Created by DB seeder',
'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
'permissions' => '{"user":"0"}',
'phone' => $this->faker->phoneNumber,
'state' => $this->faker->stateAbbr,
'username' => $this->faker->username,
'zip' => $this->faker->postcode,
'phone' => $this->faker->phoneNumber(),
'state' => $this->faker->stateAbbr(),
'username' => $this->faker->username(),
'zip' => $this->faker->postcode(),
];
}
@ -78,7 +79,9 @@ class UserFactory extends Factory
return $this->state(function () {
return [
'permissions' => '{"admin":"1"}',
'manager_id' => rand(1, 2),
'manager_id' => function () {
return User::where('permissions->superuser', '1')->first() ?? User::factory()->firstAdmin();
},
];
});
}

View file

@ -23,7 +23,7 @@ class AddEolDateOnAssetsTable extends Migration
});
// Chunk the model query to get the models that do have an EOL date
AssetModel::whereNotNull('eol')->with('assets')->chunk(200, function ($models) {
AssetModel::whereNotNull('eol')->chunk(10, function ($models) {
foreach ($models as $model) {
foreach ($model->assets as $asset) {

View file

@ -0,0 +1,39 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddsWebhookOptionToSettingsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('settings', function (Blueprint $table) {
$table->string('webhook_selected')->after('slack_botname')->default('slack')->nullable();
$table->renameColumn('slack_botname', 'webhook_botname');
$table->renameColumn('slack_endpoint', 'webhook_endpoint');
$table->renameColumn('slack_channel', 'webhook_channel');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('settings', function (Blueprint $table) {
$table->dropColumn('webhook_selected');
$table->renameColumn('webhook_botname', 'slack_botname');
$table->renameColumn('webhook_endpoint', 'slack_endpoint');
$table->renameColumn('webhook_channel', 'slack_channel');
});
}
}

View file

@ -0,0 +1,38 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
use App\Models\Setting;
class UpdateSlackSetting extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
/*
* This is a dumb migration that would only affect a few people that would have been caught in the back-in-time
* migration change to change Slack to slack
*/
$settings = Setting::where('webhook_selected', '=', 'Slack')->get();
foreach($settings as $setting){
$setting->webhook_selected = 'slack';
$setting->save();
}
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
//
}
}

View file

@ -3,6 +3,9 @@
namespace Database\Seeders;
use App\Models\Accessory;
use App\Models\Location;
use App\Models\Supplier;
use App\Models\User;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
@ -14,10 +17,45 @@ class AccessorySeeder extends Seeder
{
Accessory::truncate();
DB::table('accessories_users')->truncate();
Accessory::factory()->count(1)->appleUsbKeyboard()->create();
Accessory::factory()->count(1)->appleBtKeyboard()->create();
Accessory::factory()->count(1)->appleMouse()->create();
Accessory::factory()->count(1)->microsoftMouse()->create();
if (! Location::count()) {
$this->call(LocationSeeder::class);
}
$locationIds = Location::all()->pluck('id');
if (! Supplier::count()) {
$this->call(SupplierSeeder::class);
}
$supplierIds = Supplier::all()->pluck('id');
$admin = User::where('permissions->superuser', '1')->first() ?? User::factory()->firstAdmin()->create();
Accessory::factory()->appleUsbKeyboard()->create([
'location_id' => $locationIds->random(),
'supplier_id' => $supplierIds->random(),
'user_id' => $admin->id,
]);
Accessory::factory()->appleBtKeyboard()->create([
'location_id' => $locationIds->random(),
'supplier_id' => $supplierIds->random(),
'user_id' => $admin->id,
]);
Accessory::factory()->appleMouse()->create([
'location_id' => $locationIds->random(),
'supplier_id' => $supplierIds->random(),
'user_id' => $admin->id,
]);
Accessory::factory()->microsoftMouse()->create([
'location_id' => $locationIds->random(),
'supplier_id' => $supplierIds->random(),
'user_id' => $admin->id,
]);
$src = public_path('/img/demo/accessories/');
$dst = 'accessories'.'/';

View file

@ -3,6 +3,9 @@
namespace Database\Seeders;
use App\Models\Actionlog;
use App\Models\Asset;
use App\Models\Location;
use App\Models\User;
use Illuminate\Database\Seeder;
class ActionlogSeeder extends Seeder
@ -10,9 +13,30 @@ class ActionlogSeeder extends Seeder
public function run()
{
Actionlog::truncate();
Actionlog::factory()->count(300)->assetCheckoutToUser()->create();
Actionlog::factory()->count(100)->assetCheckoutToLocation()->create();
if (! Asset::count()) {
$this->call(AssetSeeder::class);
}
if (! Location::count()) {
$this->call(LocationSeeder::class);
}
$admin = User::where('permissions->superuser', '1')->first() ?? User::factory()->firstAdmin()->create();
Actionlog::factory()
->count(300)
->assetCheckoutToUser()
->create(['user_id' => $admin->id]);
Actionlog::factory()
->count(100)
->assetCheckoutToLocation()
->create(['user_id' => $admin->id]);
Actionlog::factory()
->count(20)
->licenseCheckoutToUser()
->create(['user_id' => $admin->id]);
}
}

View file

@ -3,6 +3,7 @@
namespace Database\Seeders;
use App\Models\AssetModel;
use App\Models\User;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
@ -13,35 +14,37 @@ class AssetModelSeeder extends Seeder
{
AssetModel::truncate();
$admin = User::where('permissions->superuser', '1')->first() ?? User::factory()->firstAdmin()->create();
// Laptops
AssetModel::factory()->count(1)->mbp13Model()->create(); // 1
AssetModel::factory()->count(1)->mbpAirModel()->create(); // 2
AssetModel::factory()->count(1)->surfaceModel()->create(); // 3
AssetModel::factory()->count(1)->xps13Model()->create(); // 4
AssetModel::factory()->count(1)->spectreModel()->create(); // 5
AssetModel::factory()->count(1)->zenbookModel()->create(); // 6
AssetModel::factory()->count(1)->yogaModel()->create(); // 7
AssetModel::factory()->count(1)->mbp13Model()->create(['user_id' => $admin->id]);
AssetModel::factory()->count(1)->mbpAirModel()->create(['user_id' => $admin->id]);
AssetModel::factory()->count(1)->surfaceModel()->create(['user_id' => $admin->id]);
AssetModel::factory()->count(1)->xps13Model()->create(['user_id' => $admin->id]);
AssetModel::factory()->count(1)->spectreModel()->create(['user_id' => $admin->id]);
AssetModel::factory()->count(1)->zenbookModel()->create(['user_id' => $admin->id]);
AssetModel::factory()->count(1)->yogaModel()->create(['user_id' => $admin->id]);
// Desktops
AssetModel::factory()->count(1)->macproModel()->create(); // 8
AssetModel::factory()->count(1)->lenovoI5Model()->create(); // 9
AssetModel::factory()->count(1)->optiplexModel()->create(); // 10
AssetModel::factory()->count(1)->macproModel()->create(['user_id' => $admin->id]);
AssetModel::factory()->count(1)->lenovoI5Model()->create(['user_id' => $admin->id]);
AssetModel::factory()->count(1)->optiplexModel()->create(['user_id' => $admin->id]);
// Conference Phones
AssetModel::factory()->count(1)->polycomModel()->create(); // 11
AssetModel::factory()->count(1)->polycomcxModel()->create(); // 12
AssetModel::factory()->count(1)->polycomModel()->create(['user_id' => $admin->id]);
AssetModel::factory()->count(1)->polycomcxModel()->create(['user_id' => $admin->id]);
// Tablets
AssetModel::factory()->count(1)->ipadModel()->create(); // 13
AssetModel::factory()->count(1)->tab3Model()->create(); // 14
AssetModel::factory()->count(1)->ipadModel()->create(['user_id' => $admin->id]);
AssetModel::factory()->count(1)->tab3Model()->create(['user_id' => $admin->id]);
// Phones
AssetModel::factory()->count(1)->iphone11Model()->create(); // 15
AssetModel::factory()->count(1)->iphone12Model()->create(); // 16
AssetModel::factory()->count(1)->iphone11Model()->create(['user_id' => $admin->id]);
AssetModel::factory()->count(1)->iphone12Model()->create(['user_id' => $admin->id]);
// Displays
AssetModel::factory()->count(1)->ultrafine()->create(); // 17
AssetModel::factory()->count(1)->ultrasharp()->create(); // 18
AssetModel::factory()->count(1)->ultrafine()->create(['user_id' => $admin->id]);
AssetModel::factory()->count(1)->ultrasharp()->create(['user_id' => $admin->id]);
$src = public_path('/img/demo/models/');
$dst = 'models'.'/';

View file

@ -3,6 +3,10 @@
namespace Database\Seeders;
use App\Models\Asset;
use App\Models\Location;
use App\Models\Supplier;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Sequence;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
@ -10,40 +14,47 @@ use Illuminate\Support\Facades\Storage;
class AssetSeeder extends Seeder
{
private $admin;
private $locationIds;
private $supplierIds;
public function run()
{
Asset::truncate();
Asset::factory()->count(1000)->laptopMbp()->create();
Asset::factory()->count(50)->laptopMbpPending()->create();
Asset::factory()->count(50)->laptopMbpArchived()->create();
Asset::factory()->count(50)->laptopAir()->create();
Asset::factory()->count(5)->laptopSurface()->create();
Asset::factory()->count(5)->laptopXps()->create();
Asset::factory()->count(5)->laptopSpectre()->create();
Asset::factory()->count(5)->laptopZenbook()->create();
Asset::factory()->count(3)->laptopYoga()->create();
Asset::factory()->count(30)->desktopMacpro()->create();
Asset::factory()->count(30)->desktopLenovoI5()->create();
Asset::factory()->count(30)->desktopOptiplex()->create();
$this->ensureLocationsSeeded();
$this->ensureSuppliersSeeded();
Asset::factory()->count(5)->confPolycom()->create();
Asset::factory()->count(2)->confPolycomcx()->create();
$this->admin = User::where('permissions->superuser', '1')->first() ?? User::factory()->firstAdmin()->create();
$this->locationIds = Location::all()->pluck('id');
$this->supplierIds = Supplier::all()->pluck('id');
Asset::factory()->count(12)->tabletIpad()->create();
Asset::factory()->count(4)->tabletTab3()->create();
Asset::factory()->count(27)->phoneIphone11()->create();
Asset::factory()->count(40)->phoneIphone12()->create();
Asset::factory()->count(10)->ultrafine()->create();
Asset::factory()->count(10)->ultrasharp()->create();
Asset::factory()->count(1000)->laptopMbp()->state(new Sequence($this->getState()))->create();
Asset::factory()->count(50)->laptopMbpPending()->state(new Sequence($this->getState()))->create();
Asset::factory()->count(50)->laptopMbpArchived()->state(new Sequence($this->getState()))->create();
Asset::factory()->count(50)->laptopAir()->state(new Sequence($this->getState()))->create();
Asset::factory()->count(5)->laptopSurface()->state(new Sequence($this->getState()))->create();
Asset::factory()->count(5)->laptopXps()->state(new Sequence($this->getState()))->create();
Asset::factory()->count(5)->laptopSpectre()->state(new Sequence($this->getState()))->create();
Asset::factory()->count(5)->laptopZenbook()->state(new Sequence($this->getState()))->create();
Asset::factory()->count(3)->laptopYoga()->state(new Sequence($this->getState()))->create();
Asset::factory()->count(30)->desktopMacpro()->state(new Sequence($this->getState()))->create();
Asset::factory()->count(30)->desktopLenovoI5()->state(new Sequence($this->getState()))->create();
Asset::factory()->count(30)->desktopOptiplex()->state(new Sequence($this->getState()))->create();
Asset::factory()->count(5)->confPolycom()->state(new Sequence($this->getState()))->create();
Asset::factory()->count(2)->confPolycomcx()->state(new Sequence($this->getState()))->create();
Asset::factory()->count(12)->tabletIpad()->state(new Sequence($this->getState()))->create();
Asset::factory()->count(4)->tabletTab3()->state(new Sequence($this->getState()))->create();
Asset::factory()->count(27)->phoneIphone11()->state(new Sequence($this->getState()))->create();
Asset::factory()->count(40)->phoneIphone12()->state(new Sequence($this->getState()))->create();
Asset::factory()->count(10)->ultrafine()->state(new Sequence($this->getState()))->create();
Asset::factory()->count(10)->ultrasharp()->state(new Sequence($this->getState()))->create();
$del_files = Storage::files('assets');
foreach ($del_files as $del_file) { // iterate files
Log::debug('Deleting: '.$del_files);
Log::debug('Deleting: ' . $del_files);
try {
Storage::disk('public')->delete('assets'.'/'.$del_files);
Storage::disk('public')->delete('assets' . '/' . $del_files);
} catch (\Exception $e) {
Log::debug($e);
}
@ -51,4 +62,27 @@ class AssetSeeder extends Seeder
DB::table('checkout_requests')->truncate();
}
private function ensureLocationsSeeded()
{
if (! Location::count()) {
$this->call(LocationSeeder::class);
}
}
private function ensureSuppliersSeeded()
{
if (! Supplier::count()) {
$this->call(SupplierSeeder::class);
}
}
private function getState()
{
return fn($sequence) => [
'rtd_location_id' => $this->locationIds->random(),
'supplier_id' => $this->supplierIds->random(),
'user_id' => $this->admin->id,
];
}
}

View file

@ -3,6 +3,7 @@
namespace Database\Seeders;
use App\Models\Category;
use App\Models\User;
use Illuminate\Database\Seeder;
class CategorySeeder extends Seeder
@ -11,20 +12,22 @@ class CategorySeeder extends Seeder
{
Category::truncate();
Category::factory()->count(1)->assetLaptopCategory()->create(); // 1
Category::factory()->count(1)->assetDesktopCategory()->create(); // 2
Category::factory()->count(1)->assetTabletCategory()->create(); // 3
Category::factory()->count(1)->assetMobileCategory()->create(); // 4
Category::factory()->count(1)->assetDisplayCategory()->create(); // 5
Category::factory()->count(1)->assetVoipCategory()->create(); // 6
Category::factory()->count(1)->assetConferenceCategory()->create(); // 7
Category::factory()->count(1)->accessoryKeyboardCategory()->create(); // 8
Category::factory()->count(1)->accessoryMouseCategory()->create(); // 9
Category::factory()->count(1)->consumablePaperCategory()->create(); // 10
Category::factory()->count(1)->consumableInkCategory()->create(); // 11
Category::factory()->count(1)->componentHddCategory()->create(); // 12
Category::factory()->count(1)->componentRamCategory()->create(); // 13
Category::factory()->count(1)->licenseGraphicsCategory()->create(); // 14
Category::factory()->count(1)->licenseOfficeCategory()->create(); // 15
$admin = User::where('permissions->superuser', '1')->first() ?? User::factory()->firstAdmin()->create();
Category::factory()->count(1)->assetLaptopCategory()->create(['user_id' => $admin->id]);
Category::factory()->count(1)->assetDesktopCategory()->create(['user_id' => $admin->id]);
Category::factory()->count(1)->assetTabletCategory()->create(['user_id' => $admin->id]);
Category::factory()->count(1)->assetMobileCategory()->create(['user_id' => $admin->id]);
Category::factory()->count(1)->assetDisplayCategory()->create(['user_id' => $admin->id]);
Category::factory()->count(1)->assetVoipCategory()->create(['user_id' => $admin->id]);
Category::factory()->count(1)->assetConferenceCategory()->create(['user_id' => $admin->id]);
Category::factory()->count(1)->accessoryKeyboardCategory()->create(['user_id' => $admin->id]);
Category::factory()->count(1)->accessoryMouseCategory()->create(['user_id' => $admin->id]);
Category::factory()->count(1)->consumablePaperCategory()->create(['user_id' => $admin->id]);
Category::factory()->count(1)->consumableInkCategory()->create(['user_id' => $admin->id]);
Category::factory()->count(1)->componentHddCategory()->create(['user_id' => $admin->id]);
Category::factory()->count(1)->componentRamCategory()->create(['user_id' => $admin->id]);
Category::factory()->count(1)->licenseGraphicsCategory()->create(['user_id' => $admin->id]);
Category::factory()->count(1)->licenseOfficeCategory()->create(['user_id' => $admin->id]);
}
}

View file

@ -2,7 +2,9 @@
namespace Database\Seeders;
use App\Models\Company;
use App\Models\Component;
use App\Models\Location;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
@ -12,9 +14,34 @@ class ComponentSeeder extends Seeder
{
Component::truncate();
DB::table('components_assets')->truncate();
Component::factory()->count(1)->ramCrucial4()->create(); // 1
Component::factory()->count(1)->ramCrucial8()->create(); // 1
Component::factory()->count(1)->ssdCrucial120()->create(); // 1
Component::factory()->count(1)->ssdCrucial240()->create(); // 1
if (! Company::count()) {
$this->call(CompanySeeder::class);
}
$companyIds = Company::all()->pluck('id');
if (! Location::count()) {
$this->call(LocationSeeder::class);
}
$locationIds = Location::all()->pluck('id');
Component::factory()->ramCrucial4()->create([
'company_id' => $companyIds->random(),
'location_id' => $locationIds->random(),
]);
Component::factory()->ramCrucial8()->create([
'company_id' => $companyIds->random(),
'location_id' => $locationIds->random(),
]);
Component::factory()->ssdCrucial120()->create([
'company_id' => $companyIds->random(),
'location_id' => $locationIds->random(),
]);
Component::factory()->ssdCrucial240()->create([
'company_id' => $companyIds->random(),
'location_id' => $locationIds->random(),
]);
}
}

View file

@ -3,6 +3,7 @@
namespace Database\Seeders;
use App\Models\Consumable;
use App\Models\User;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
@ -12,8 +13,11 @@ class ConsumableSeeder extends Seeder
{
Consumable::truncate();
DB::table('consumables_users')->truncate();
Consumable::factory()->count(1)->cardstock()->create(); // 1
Consumable::factory()->count(1)->paper()->create(); // 2
Consumable::factory()->count(1)->ink()->create(); // 3
$admin = User::where('permissions->superuser', '1')->first() ?? User::factory()->firstAdmin()->create();
Consumable::factory()->count(1)->cardstock()->create(['user_id' => $admin->id]);
Consumable::factory()->count(1)->paper()->create(['user_id' => $admin->id]);
Consumable::factory()->count(1)->ink()->create(['user_id' => $admin->id]);
}
}

View file

@ -3,15 +3,6 @@
namespace Database\Seeders;
use App\Models\Setting;
use Database\Seeders\AccessorySeeder;
use Database\Seeders\ActionlogSeeder;
use Database\Seeders\AssetModelSeeder;
use Database\Seeders\AssetSeeder;
use Database\Seeders\CategorySeeder;
use Database\Seeders\CompanySeeder;
use Database\Seeders\ComponentSeeder;
use Database\Seeders\ConsumableSeeder;
use Database\Seeders\CustomFieldSeeder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\Artisan;
@ -38,9 +29,9 @@ class DatabaseSeeder extends Seeder
$this->call(CompanySeeder::class);
$this->call(CategorySeeder::class);
$this->call(LocationSeeder::class);
$this->call(DepartmentSeeder::class);
$this->call(UserSeeder::class);
$this->call(DepreciationSeeder::class);
$this->call(DepartmentSeeder::class);
$this->call(ManufacturerSeeder::class);
$this->call(SupplierSeeder::class);
$this->call(AssetModelSeeder::class);

View file

@ -3,6 +3,8 @@
namespace Database\Seeders;
use App\Models\Department;
use App\Models\Location;
use App\Models\User;
use Illuminate\Database\Seeder;
class DepartmentSeeder extends Seeder
@ -10,11 +12,43 @@ class DepartmentSeeder extends Seeder
public function run()
{
Department::truncate();
Department::factory()->count(1)->hr()->create(); // 1
Department::factory()->count(1)->engineering()->create(); // 2
Department::factory()->count(1)->marketing()->create(); // 3
Department::factory()->count(1)->client()->create(); // 4
Department::factory()->count(1)->product()->create(); // 5
Department::factory()->count(1)->silly()->create(); // 6
if (! Location::count()) {
$this->call(LocationSeeder::class);
}
$locationIds = Location::all()->pluck('id');
$admin = User::where('permissions->superuser', '1')->first() ?? User::factory()->firstAdmin()->create();
Department::factory()->count(1)->hr()->create([
'location_id' => $locationIds->random(),
'user_id' => $admin->id,
]);
Department::factory()->count(1)->engineering()->create([
'location_id' => $locationIds->random(),
'user_id' => $admin->id,
]);
Department::factory()->count(1)->marketing()->create([
'location_id' => $locationIds->random(),
'user_id' => $admin->id,
]);
Department::factory()->count(1)->client()->create([
'location_id' => $locationIds->random(),
'user_id' => $admin->id,
]);
Department::factory()->count(1)->product()->create([
'location_id' => $locationIds->random(),
'user_id' => $admin->id,
]);
Department::factory()->count(1)->silly()->create([
'location_id' => $locationIds->random(),
'user_id' => $admin->id,
]);
}
}

View file

@ -3,6 +3,7 @@
namespace Database\Seeders;
use App\Models\Depreciation;
use App\Models\User;
use Illuminate\Database\Seeder;
class DepreciationSeeder extends Seeder
@ -10,8 +11,11 @@ class DepreciationSeeder extends Seeder
public function run()
{
Depreciation::truncate();
Depreciation::factory()->count(1)->computer()->create(); // 1
Depreciation::factory()->count(1)->display()->create(); // 2
Depreciation::factory()->count(1)->mobilePhones()->create(); // 3
$admin = User::where('permissions->superuser', '1')->first() ?? User::factory()->firstAdmin()->create();
Depreciation::factory()->count(1)->computer()->create(['user_id' => $admin->id]);
Depreciation::factory()->count(1)->display()->create(['user_id' => $admin->id]);
Depreciation::factory()->count(1)->mobilePhones()->create(['user_id' => $admin->id]);
}
}

View file

@ -2,8 +2,11 @@
namespace Database\Seeders;
use App\Models\Category;
use App\Models\License;
use App\Models\LicenseSeat;
use App\Models\Supplier;
use App\Models\User;
use Illuminate\Database\Seeder;
class LicenseSeeder extends Seeder
@ -12,9 +15,43 @@ class LicenseSeeder extends Seeder
{
License::truncate();
LicenseSeat::truncate();
License::factory()->count(1)->photoshop()->create();
License::factory()->count(1)->acrobat()->create();
License::factory()->count(1)->indesign()->create();
License::factory()->count(1)->office()->create();
if (! Category::count()) {
$this->call(CategorySeeder::class);
}
$categoryIds = Category::all()->pluck('id');
if (! Supplier::count()) {
$this->call(SupplierSeeder::class);
}
$supplierIds = Supplier::all()->pluck('id');
$admin = User::where('permissions->superuser', '1')->first() ?? User::factory()->firstAdmin()->create();
License::factory()->count(1)->photoshop()->create([
'category_id' => $categoryIds->random(),
'supplier_id' => $supplierIds->random(),
'user_id' => $admin->id,
]);
License::factory()->count(1)->acrobat()->create([
'category_id' => $categoryIds->random(),
'supplier_id' => $supplierIds->random(),
'user_id' => $admin->id,
]);
License::factory()->count(1)->indesign()->create([
'category_id' => $categoryIds->random(),
'supplier_id' => $supplierIds->random(),
'user_id' => $admin->id,
]);
License::factory()->count(1)->office()->create([
'category_id' => $categoryIds->random(),
'supplier_id' => $supplierIds->random(),
'user_id' => $admin->id,
]);
}
}

View file

@ -3,6 +3,7 @@
namespace Database\Seeders;
use App\Models\Manufacturer;
use App\Models\User;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
@ -12,17 +13,20 @@ class ManufacturerSeeder extends Seeder
public function run()
{
Manufacturer::truncate();
Manufacturer::factory()->count(1)->apple()->create(); // 1
Manufacturer::factory()->count(1)->microsoft()->create(); // 2
Manufacturer::factory()->count(1)->dell()->create(); // 3
Manufacturer::factory()->count(1)->asus()->create(); // 4
Manufacturer::factory()->count(1)->hp()->create(); // 5
Manufacturer::factory()->count(1)->lenovo()->create(); // 6
Manufacturer::factory()->count(1)->lg()->create(); // 7
Manufacturer::factory()->count(1)->polycom()->create(); // 8
Manufacturer::factory()->count(1)->adobe()->create(); // 9
Manufacturer::factory()->count(1)->avery()->create(); // 10
Manufacturer::factory()->count(1)->crucial()->create(); // 10
$admin = User::where('permissions->superuser', '1')->first() ?? User::factory()->firstAdmin()->create();
Manufacturer::factory()->count(1)->apple()->create(['user_id' => $admin->id]);
Manufacturer::factory()->count(1)->microsoft()->create(['user_id' => $admin->id]);
Manufacturer::factory()->count(1)->dell()->create(['user_id' => $admin->id]);
Manufacturer::factory()->count(1)->asus()->create(['user_id' => $admin->id]);
Manufacturer::factory()->count(1)->hp()->create(['user_id' => $admin->id]);
Manufacturer::factory()->count(1)->lenovo()->create(['user_id' => $admin->id]);
Manufacturer::factory()->count(1)->lg()->create(['user_id' => $admin->id]);
Manufacturer::factory()->count(1)->polycom()->create(['user_id' => $admin->id]);
Manufacturer::factory()->count(1)->adobe()->create(['user_id' => $admin->id]);
Manufacturer::factory()->count(1)->avery()->create(['user_id' => $admin->id]);
Manufacturer::factory()->count(1)->crucial()->create(['user_id' => $admin->id]);
$src = public_path('/img/demo/manufacturers/');
$dst = 'manufacturers'.'/';

View file

@ -3,6 +3,7 @@
namespace Database\Seeders;
use App\Models\Statuslabel;
use App\Models\User;
use Illuminate\Database\Seeder;
class StatuslabelSeeder extends Seeder
@ -10,12 +11,27 @@ class StatuslabelSeeder extends Seeder
public function run()
{
Statuslabel::truncate();
Statuslabel::factory()->rtd()->create(['name' => 'Ready to Deploy']);
Statuslabel::factory()->pending()->create(['name' => 'Pending']);
Statuslabel::factory()->archived()->create(['name' => 'Archived']);
Statuslabel::factory()->outForDiagnostics()->create();
Statuslabel::factory()->outForRepair()->create();
Statuslabel::factory()->broken()->create();
Statuslabel::factory()->lost()->create();
$admin = User::where('permissions->superuser', '1')->first() ?? User::factory()->firstAdmin()->create();
Statuslabel::factory()->rtd()->create([
'name' => 'Ready to Deploy',
'user_id' => $admin->id,
]);
Statuslabel::factory()->pending()->create([
'name' => 'Pending',
'user_id' => $admin->id,
]);
Statuslabel::factory()->archived()->create([
'name' => 'Archived',
'user_id' => $admin->id,
]);
Statuslabel::factory()->outForDiagnostics()->create(['user_id' => $admin->id]);
Statuslabel::factory()->outForRepair()->create(['user_id' => $admin->id]);
Statuslabel::factory()->broken()->create(['user_id' => $admin->id]);
Statuslabel::factory()->lost()->create(['user_id' => $admin->id]);
}
}

View file

@ -2,7 +2,10 @@
namespace Database\Seeders;
use App\Models\Company;
use App\Models\Department;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Sequence;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Log;
@ -17,11 +20,53 @@ class UserSeeder extends Seeder
public function run()
{
User::truncate();
User::factory()->count(1)->firstAdmin()->create();
User::factory()->count(1)->snipeAdmin()->create();
User::factory()->count(3)->superuser()->create();
User::factory()->count(3)->admin()->create();
User::factory()->count(50)->viewAssets()->create();
if (! Company::count()) {
$this->call(CompanySeeder::class);
}
$companyIds = Company::all()->pluck('id');
if (! Department::count()) {
$this->call(DepartmentSeeder::class);
}
$departmentIds = Department::all()->pluck('id');
User::factory()->count(1)->firstAdmin()
->state(new Sequence(fn($sequence) => [
'company_id' => $companyIds->random(),
'department_id' => $departmentIds->random(),
]))
->create();
User::factory()->count(1)->snipeAdmin()
->state(new Sequence(fn($sequence) => [
'company_id' => $companyIds->random(),
'department_id' => $departmentIds->random(),
]))
->create();
User::factory()->count(3)->superuser()
->state(new Sequence(fn($sequence) => [
'company_id' => $companyIds->random(),
'department_id' => $departmentIds->random(),
]))
->create();
User::factory()->count(3)->admin()
->state(new Sequence(fn($sequence) => [
'company_id' => $companyIds->random(),
'department_id' => $departmentIds->random(),
]))
->create();
User::factory()->count(50)->viewAssets()
->state(new Sequence(fn($sequence) => [
'company_id' => $companyIds->random(),
'department_id' => $departmentIds->random(),
]))
->create();
$src = public_path('/img/demo/avatars/');
$dst = 'avatars'.'/';

18
package-lock.json generated
View file

@ -1533,9 +1533,9 @@
}
},
"@types/eslint": {
"version": "8.4.5",
"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.5.tgz",
"integrity": "sha512-dhsC09y1gpJWnK+Ff4SGvCuSnk9DaU0BJZSzOwa6GVSg65XtTugLBITDAAzRU5duGBoXBHpdR/9jHGxJjNflJQ==",
"version": "8.21.2",
"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.21.2.tgz",
"integrity": "sha512-EMpxUyystd3uZVByZap1DACsMXvb82ypQnGn89e1Y0a+LYu3JJscUd/gqhRsVFDkaD2MIiWo0MT8EfXr3DGRKw==",
"requires": {
"@types/estree": "*",
"@types/json-schema": "*"
@ -4768,9 +4768,9 @@
}
},
"enhanced-resolve": {
"version": "5.10.0",
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz",
"integrity": "sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ==",
"version": "5.12.0",
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz",
"integrity": "sha512-QHTXI/sZQmko1cbDoNAa3mJ5qhWUUNAq3vR0/YiD379fWQrcfuoX1+HW2S0MTt7XmoPLapdaDKUtelUSPic7hQ==",
"requires": {
"graceful-fs": "^4.2.4",
"tapable": "^2.2.0"
@ -19758,9 +19758,9 @@
}
},
"webpack": {
"version": "5.74.0",
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.74.0.tgz",
"integrity": "sha512-A2InDwnhhGN4LYctJj6M1JEaGL7Luj6LOmyBHjcI8529cm5p6VXiTIW2sn6ffvEAKmveLzvu4jrihwXtPojlAA==",
"version": "5.76.1",
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.76.1.tgz",
"integrity": "sha512-4+YIK4Abzv8172/SGqObnUjaIHjLEuUasz9EwQj/9xmPPkYJy2Mh03Q/lJfSD3YLzbxy5FeTq5Uw0323Oh6SJQ==",
"requires": {
"@types/eslint-scope": "^3.7.3",
"@types/estree": "^0.0.51",

View file

@ -55,6 +55,6 @@
"tableexport.jquery.plugin": "1.26.0",
"tether": "^1.4.0",
"vue-resource": "^1.5.2",
"webpack": "^5.74.0"
"webpack": "^5.76.0"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 766 B

Binary file not shown.

BIN
public/js/dist/all.js vendored

Binary file not shown.

View file

@ -1,5 +1,5 @@
{
"/js/build/app.js": "/js/build/app.js?id=da037f537476ebca094531163cb611f5",
"/js/build/app.js": "/js/build/app.js?id=bcb572126085fb7637accdcff1e0c0c6",
"/css/dist/skins/skin-blue.css": "/css/dist/skins/skin-blue.css?id=f677207c6cf9678eb539abecb408c374",
"/css/build/overrides.css": "/css/build/overrides.css?id=d9175e3d9b9074397343dddebfe23888",
"/css/build/app.css": "/css/build/app.css?id=dcb8aa9f4501a370214a67442e88daf0",
@ -34,7 +34,7 @@
"/css/dist/bootstrap-table.css": "/css/dist/bootstrap-table.css?id=ee4896df8b8f008ce73a9a0c2549aefd",
"/js/build/vendor.js": "/js/build/vendor.js?id=47ecbb4bb3b0e02315f391caadbdf971",
"/js/dist/bootstrap-table.js": "/js/dist/bootstrap-table.js?id=14d9a2affec7b066d20fcba2e6e67ad2",
"/js/dist/all.js": "/js/dist/all.js?id=758f256419ccaf4b4266da3bbc742b0b",
"/js/dist/all.js": "/js/dist/all.js?id=eb7becb7a5a2ebf0dae7926190d95832",
"/css/dist/skins/skin-green.min.css": "/css/dist/skins/skin-green.min.css?id=0a82a6ae6bb4e58fe62d162c4fb50397",
"/css/dist/skins/skin-green-dark.min.css": "/css/dist/skins/skin-green-dark.min.css?id=c0d21166315b7c2cdd4819fa4a5e4d1e",
"/css/dist/skins/skin-black.min.css": "/css/dist/skins/skin-black.min.css?id=76482123f6c70e866d6b971ba91de7bb",

View file

@ -1,36 +0,0 @@
<style scoped>
</style>
<template>
<div class="col-md-12" :class="alertType">
<div class="alert" :class="alertClassName">
<button type="button" class="close" @click="hideEvent">&times;</button>
<i class="fas fa-check faa-pulse animated" aria-hidden="true" v-show="alertType == 'success'"></i>
<strong>{{ title }} </strong>
<slot></slot>
</div>
</div>
</template>
<script>
export default {
/*
* The component's data.
*/
props: ['alertType', 'title'],
computed: {
alertClassName() {
return 'alert-' + this.alertType;
}
},
methods: {
hideEvent() {
this.$emit('hide');
}
}
}
</script>

View file

@ -1,42 +0,0 @@
<style scoped>
</style>
<template>
<div class="box" v-if="errors">
<div class="box-body">
<div class="alert alert-warning">
<strong>Warning</strong> Some Errors occured while importing
</div>
<div class="errors-table">
<table class="table table-striped table-bordered" id="errors-table">
<thead>
<th>Item</th>
<th>Errors</th>
</thead>
<tbody>
<tr v-for="(error, item) in errors">
<td>{{ item }}</td>
<td v-for="(value, field) in error">
<b>{{ field }}:</b>
<span v-for="errorString in value">{{errorString[0]}}</span>
<br />
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</template>
<script>
export default {
/*
* The component's data.
*/
props: ['errors'],
}
</script>

View file

@ -1,327 +0,0 @@
<template>
<tr v-show="processDetail">
<td colspan="5">
<div class="col-md-12">
<div class="row">
<div class="dynamic-form-row">
<div class="col-md-5 col-xs-12">
<label for="import-type">Import Type:</label>
</div>
<div class="col-md-7 col-xs-12">
<select2 :options="options.importTypes" v-model="options.importType" required>
<option disabled value="0"></option>
</select2>
</div>
</div><!-- /dynamic-form-row -->
<div class="dynamic-form-row">
<div class="col-md-5 col-xs-12">
<label for="import-update">Update Existing Values?:</label>
</div>
<div class="col-md-7 col-xs-12">
<input type="checkbox" class="icheckbox_minimal" name="import-update" v-model="options.update">
</div>
</div><!-- /dynamic-form-row -->
<div class="dynamic-form-row">
<div class="col-md-5 col-xs-12">
<label for="send-welcome">Send Welcome Email for new Users?</label>
</div>
<div class="col-md-7 col-xs-12">
<input type="checkbox" class="icheckbox_minimal" name="send-welcome" v-model="options.send_welcome">
</div>
</div><!-- /dynamic-form-row -->
<div class="dynamic-form-row">
<div class="col-md-5 col-xs-12">
<label for="run-backup">Backup before importing?</label>
</div>
<div class="col-md-7 col-xs-12">
<input type="checkbox" class="icheckbox_minimal" name="run-backup" v-model="options.run_backup">
</div>
</div><!-- /dynamic-form-row -->
<div class="alert col-md-8 col-md-offset-2" style="text-align:left"
:class="alertClass"
v-if="statusText">
{{ this.statusText }}
</div><!-- /alert -->
</div> <!-- /div row -->
<div class="row">
<div class="col-md-12" style="padding-top: 30px;">
<div class="col-md-4 text-right"><h4>Header Field</h4></div>
<div class="col-md-4"><h4>Import Field</h4></div>
<div class="col-md-4"><h4>Sample Value</h4></div>
</div>
</div><!-- /div row -->
<template v-for="(header, index) in file.header_row">
<div class="row">
<div class="col-md-12">
<div class="col-md-4 text-right">
<label :for="header" class="control-label">{{ header }}</label>
</div>
<div class="col-md-4 form-group">
<div required>
<select2 :options="columns" v-model="columnMappings[header]">
<option value="0">Do Not Import</option>
</select2>
</div>
</div>
<div class="col-md-4">
<p class="form-control-static">{{ activeFile.first_row[index] }}</p>
</div>
</div><!-- /div col-md-8 -->
</div><!-- /div row -->
</template>
<div class="row">
<div class="col-md-6 col-md-offset-2 text-right" style="padding-top: 20px;">
<button type="button" class="btn btn-sm btn-default" @click="processDetail = false">Cancel</button>
<button type="submit" class="btn btn-sm btn-primary" @click="postSave">Import</button>
<br><br>
</div>
</div><!-- /div row -->
<div class="row">
<div class="alert col-md-8 col-md-offset-2" style="padding-top: 20px;"
:class="alertClass"
v-if="statusText">
{{ this.statusText }}
</div>
</div><!-- /div row -->
</div><!-- /div v-show -->
</td>
</tr>
</template>
<script>
var baseUrl = $('meta[name="baseUrl"]').attr('content');
export default {
props: ['file', 'customFields'],
data() {
return {
activeFile: this.file,
processDetail: false,
statusText: null,
statusType: null,
options: {
importType: this.file.import_type,
update: false,
send_welcome: false,
run_backup: false,
importTypes: [
{ id: 'asset', text: 'Assets' },
{ id: 'accessory', text: 'Accessories' },
{ id: 'consumable', text: 'Consumables' },
{ id: 'component', text: 'Components' },
{ id: 'license', text: 'Licenses' },
{ id: 'user', text: 'Users' }
],
statusText: null,
},
columnOptions: {
general: [
{id: 'category', text: 'Category' },
{id: 'company', text: 'Company' },
{id: 'email', text: 'Email' },
{id: 'item_name', text: 'Item Name' },
{id: 'location', text: 'Location' },
{id: 'maintained', text: 'Maintained' },
{id: 'manufacturer', text: 'Manufacturer' },
{id: 'order_number', text: 'Order Number' },
{id: 'purchase_cost', text: 'Purchase Cost' },
{id: 'purchase_date', text: 'Purchase Date' },
{id: 'quantity', text: 'Quantity' },
{id: 'requestable', text: 'Requestable' },
{id: 'serial', text: 'Serial Number' },
{id: 'supplier', text: 'Supplier' },
{id: 'username', text: 'Username' },
{id: 'department', text: 'Department' },
],
accessories:[
{id: 'model_number', text: 'Model Number'},
{id: 'notes', text: 'Notes' },
],
assets: [
{id: 'asset_tag', text: 'Asset Tag' },
{id: 'asset_model', text: 'Model Name' },
{id: 'checkout_class', text: 'Checkout Type' },
{id: 'checkout_location', text: 'Checkout Location' },
{id: 'image', text: 'Image Filename' },
{id: 'model_number', text: 'Model Number' },
{id: 'asset_notes', text: 'Asset Notes' },
{id: 'model_notes', text: 'Model Notes' },
{id: 'full_name', text: 'Full Name' },
{id: 'status', text: 'Status' },
{id: 'warranty_months', text: 'Warranty Months' },
{id: 'last_audit_date', text: 'Last Audit Date' },
{id: 'next_audit_date', text: 'Audit Date' },
{id: 'byod', text: 'BYOD' },
],
consumables: [
{id: 'item_no', text: "Item Number"},
{id: 'model_number', text: "Model Number"},
{id: 'min_amt', text: "Minimum Quantity"},
{id: 'notes', text: 'Notes' },
],
licenses: [
{id: 'asset_tag', text: 'Assigned To Asset'},
{id: 'expiration_date', text: 'Expiration Date' },
{id: 'full_name', text: 'Full Name' },
{id: 'license_email', text: 'Licensed To Email' },
{id: 'license_name', text: 'Licensed To Name' },
{id: 'notes', text: 'Notes' },
{id: 'purchase_order', text: 'Purchase Order' },
{id: 'reassignable', text: 'Reassignable' },
{id: 'seats', text: 'Seats' },
],
users: [
{id: 'employee_num', text: 'Employee Number' },
{id: 'first_name', text: 'First Name' },
{id: 'jobtitle', text: 'Job Title' },
{id: 'last_name', text: 'Last Name' },
{id: 'phone_number', text: 'Phone Number' },
{id: 'manager_first_name', text: 'Manager First Name' },
{id: 'notes', text: 'Notes' },
{id: 'manager_last_name', text: 'Manager Last Name' },
{id: 'activated', text: 'Activated' },
{id: 'address', text: 'Address' },
{id: 'city', text: 'City' },
{id: 'state', text: 'State' },
{id: 'country', text: 'Country' },
{id: 'zip', text: 'ZIP' },
{id: 'remote', text: 'Remote'},
{id: 'vip', text: 'VIP'},
],
customFields: this.customFields,
},
columnMappings: this.file.field_map || {},
activeColumn: null,
}
},
created() {
window.eventHub.$on('showDetails', this.toggleExtendedDisplay)
this.populateSelect2ActiveItems();
},
computed: {
columns() {
// function to sort objects by their display text.
function sorter(a,b) {
if (a.text < b.text)
return -1;
if (a.text > b.text)
return 1;
return 0;
}
switch(this.options.importType) {
case 'asset':
return this.columnOptions.general
.concat(this.columnOptions.assets)
.concat(this.columnOptions.customFields)
.sort(sorter);
case 'accessory':
return this.columnOptions.general
.concat(this.columnOptions.accessories)
.sort(sorter);
case 'consumable':
console.log('Returned consumable');
return this.columnOptions.general
.concat(this.columnOptions.consumables)
.sort(sorter);
case 'license':
return this.columnOptions.general.concat(this.columnOptions.licenses).sort(sorter);
case 'user':
return this.columnOptions.general.concat(this.columnOptions.users).sort(sorter);
}
return this.columnOptions.general;
},
alertClass() {
if(this.statusType=='success') {
return 'alert-success';
}
if(this.statusType=='error') {
return 'alert-danger';
}
return 'alert-info';
},
},
watch: {
columns() {
this.populateSelect2ActiveItems();
}
},
methods: {
postSave() {
console.log('saving');
console.log(this.options.importType);
if(!this.options.importType) {
this.statusType='error';
this.statusText= "An import type is required... ";
return;
}
this.statusType='pending';
this.statusText = "Processing...";
this.$http.post(baseUrl + 'api/v1/imports/process/' + this.file.id, {
'import-update': this.options.update,
'send-welcome': this.options.send_welcome,
'import-type': this.options.importType,
'run-backup': this.options.run_backup,
'column-mappings': this.columnMappings
}).then( ({body}) => {
// Success
this.statusType="success";
this.statusText = "Success... Redirecting.";
window.location.href = body.messages.redirect_url;
}, ({body}) => {
// Failure
if(body.status == 'import-errors') {
window.eventHub.$emit('importErrors', body.messages);
this.statusType='error';
this.statusText = "Error";
} else {
this.$emit('alert', {
message: body.messages,
type: "danger",
visible: true,
})
}
this.displayImportModal=false;
});
},
populateSelect2ActiveItems() {
if(this.file.field_map == null) {
// Begin by populating the active selection in dropdowns with blank values.
for (var i=0; i < this.file.header_row.length; i++) {
this.$set(this.columnMappings, this.file.header_row[i], null);
}
// Then, for any values that have a likely match, we make that active.
for(var j=0; j < this.columns.length; j++) {
let column = this.columns[j];
let lower = this.file.header_row.map((value) => value.toLowerCase());
let index = lower.indexOf(column.text.toLowerCase())
if(index != -1) {
this.$set(this.columnMappings, this.file.header_row[index], column.id)
}
}
}
},
toggleExtendedDisplay(fileId) {
if(fileId == this.file.id) {
this.processDetail = !this.processDetail
}
},
updateModel(header, value) {
this.columnMappings[header] = value;
}
},
components: {
select2: require('../select2.vue').default
}
}
</script>

View file

@ -1,130 +0,0 @@
<script>
require('blueimp-file-upload');
var baseUrl = $('meta[name="baseUrl"]').attr('content');
export default {
/*
* The component's data.
*/
data() {
return {
files: [],
displayImportModal: false,
activeFile: null,
alert: {
type: null,
message: null,
visible: false,
},
importErrors: null,
progress: {
currentClass: "progress-bar-warning",
currentPercent: "0",
statusText: '',
visible: false
},
customFields: [],
};
},
mounted() {
window.eventHub.$on('importErrors', this.updateImportErrors);
this.fetchFiles();
this.fetchCustomFields();
let vm = this;
$('#fileupload').fileupload({
dataType: 'json',
done(e, data) {
vm.progress.currentClass="progress-bar-success";
vm.progress.statusText = "Success!";
vm.files = data.result.files.concat(vm.files);
console.log(data.result.header_row);
},
add(e, data) {
data.headers = {
"X-Requested-With": 'XMLHttpRequest',
"X-CSRF-TOKEN": Laravel.csrfToken
};
data.process().done( () => {data.submit();});
vm.progress.visible=true;
},
progress(e, data) {
var progress = parseInt((data.loaded / data.total * 100, 10));
vm.progress.currentPercent = progress;
vm.progress.statusText = progress+'% Complete';
},
fail(e, data) {
vm.progress.currentClass = "progress-bar-danger";
// Display any errors returned from the $.ajax()
vm.progress.statusText = data.jqXHR.responseJSON.messages;
}
})
},
methods: {
fetchFiles() {
this.$http.get(baseUrl + 'api/v1/imports')
.then( ({data}) => this.files = data, // Success
//Fail
(response) => {
this.alert.type="danger";
this.alert.visible=true;
this.alert.message="Something went wrong fetching files...";
});
},
fetchCustomFields() {
this.$http.get(baseUrl + 'api/v1/fields')
.then( ({data}) => {
data = data.rows;
data.forEach((item) => {
this.customFields.push({
'id': item.db_column_name,
'text': item.name,
})
})
});
},
deleteFile(file, key) {
this.$http.delete(baseUrl + 'api/v1/imports/' + file.id)
.then(
// Success, remove file from array.
(response) => {
this.files.splice(key, 1);
this.alert.type = response.body.status; // A failed delete can still cause a 200 status code.
this.alert.visible = true;
this.alert.message = response.body.messages;
},
(response) => {// Fail
// this.files.splice(key, 1);
this.alert.type="error";
this.alert.visible=true;
this.alert.message=response.body.messages;
}
);
},
toggleEvent(fileId) {
window.eventHub.$emit('showDetails', fileId)
},
updateAlert(alert) {
this.alert = alert;
},
updateImportErrors(errors) {
this.importErrors = errors;
},
},
computed: {
progressWidth() {
return "width: "+this.progress.currentPercent*10+'%';
}
},
components: {
alert: require('../alert.vue').default,
errors: require('./importer-errors.vue').default,
importFile: require('./importer-file.vue').default,
}
}
</script>

View file

@ -605,3 +605,54 @@ function htmlEntities(str) {
};
})(jQuery);
/**
* Universal Livewire Select2 and iCheck integration
*
* How to use:
*
* 1. Set the class of your select2 elements to 'livewire-select2' and your icheck elements to 'livewire-icheck' (as appropriate).
* (For iCheck, you may still need to apply the other iCheck classes like 'minimal' or 'iCheck')
* 2. Name your element to match a property in your Livewire component
* 3. Add an attribute called 'data-livewire-component' that points to $_instance->id (via `{{ }}` if you're in a blade,
* or just $_instance->id if not).
* 4. For iCheck, you need to wrap the 'checkbox' element with wire:ignore - perhaps in the <label> if it wraps the
* <input> element, or just put a <span wire:ignore></span> around just the input element.
* 5. If you have dynamically shown/hidden checkboxes, you might need to initialize iCheck on them on component page-load.
* Just use $('.livewire-icheck').iCheck(), or for the minimal-style, use:
*
* $('input[type="checkbox"].minimal.livewire-icheck, input[type="radio"].minimal.livewire-icheck').iCheck({
* checkboxClass: 'icheckbox_minimal-blue',
* radioClass: 'iradio_minimal-blue'
* });
*
* (which is stolen from above here in this JS file)
*/
$(function () {
$('.livewire-select2').select2()
$(document).on('select2:select', '.livewire-select2', function (event) {
var target = $(event.target)
if(!event.target.name || !target.data('livewire-component')) {
console.error("You need to set both name (which should match a Livewire property) and data-livewire-component on your Livewire-ed select2 elements!")
console.error("For data-livewire-component, you probably want to use $_instance->id or {{ $_instance->id }}, as appropriate")
return false
}
window.livewire.find(target.data('livewire-component')).set(event.target.name, this.options[this.selectedIndex].value)
})
window.livewire.hook('message.processed', function (el,component) {
$('.livewire-select2').select2();
//$('.livewire-icheck').iCheck(); //this seems to blow up pretty badly.
});
$(document).on('ifToggled', '.livewire-icheck', function (event) {
if(!event.target.name || !$(event.target).data('livewire-component')) {
console.error("You need to set both name (which should match a Livewire property) and data-livewire-component on your iCheck elements!")
console.error("For data-livewire-component, you probably want to use $_instance->id or {{ $_instance->id }}, as appropriate")
return false
}
window.livewire.find($(event.target).data('livewire-component')).set(event.target.name, event.target.checked)
})
})

View file

@ -26,10 +26,11 @@ Vue.component(
require('./components/passport/PersonalAccessTokens.vue').default
);
Vue.component(
'importer',
require('./components/importer/importer.vue').default
);
// This component has been removed and replaced with a Livewire implementation
// Vue.component(
// 'importer',
// require('./components/importer/importer.vue').default
// );
// This component has been removed and replaced with a Livewire implementation
// Vue.component(

Some files were not shown because too many files have changed in this diff Show more