mirror of
https://github.com/snipe/snipe-it.git
synced 2024-12-25 05:34:06 -08:00
Merge branch 'develop' into generalize_webhooks
This commit is contained in:
commit
27a2ed5c79
|
@ -2837,6 +2837,33 @@
|
|||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "AndrewSav",
|
||||
"name": "Andrew Savinykh",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/658865?v=4",
|
||||
"profile": "https://github.com/AndrewSav",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "kenchan0130",
|
||||
"name": "Tadayuki Onishi",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/1155067?v=4",
|
||||
"profile": "https://kenchan0130.github.io",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "floschoepfer",
|
||||
"name": "Florian",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/112496896?v=4",
|
||||
"profile": "https://github.com/floschoepfer",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
75
.env.testing
75
.env.testing
|
@ -1,75 +0,0 @@
|
|||
# --------------------------------------------
|
||||
# REQUIRED: BASIC APP SETTINGS
|
||||
# --------------------------------------------
|
||||
APP_ENV=testing
|
||||
APP_DEBUG=true
|
||||
APP_KEY=base64:glJpcM7BYwWiBggp3SQ/+NlRkqsBQMaGEOjemXqJzOU=
|
||||
APP_URL=http://localhost:8000
|
||||
APP_TIMEZONE='US/Pacific'
|
||||
APP_LOCALE=en
|
||||
FILESYSTEM_DISK=local
|
||||
|
||||
# --------------------------------------------
|
||||
# REQUIRED: DATABASE SETTINGS
|
||||
# --------------------------------------------
|
||||
DB_CONNECTION=sqlite_testing
|
||||
DB_HOST=localhost
|
||||
DB_PORT=3306
|
||||
DB_DATABASE=testing.sqlite
|
||||
DB_USERNAME=null
|
||||
DB_PASSWORD=null
|
||||
|
||||
# --------------------------------------------
|
||||
# REQUIRED: OUTGOING MAIL SERVER SETTINGS
|
||||
# --------------------------------------------
|
||||
MAIL_DRIVER=log
|
||||
MAIL_HOST=email-smtp.us-west-2.amazonaws.com
|
||||
MAIL_PORT=587
|
||||
MAIL_USERNAME=YOURUSERNAME
|
||||
MAIL_PASSWORD=YOURPASSWORD
|
||||
MAIL_ENCRYPTION=null
|
||||
MAIL_FROM_ADDR=you@example.com
|
||||
MAIL_FROM_NAME=Snipe-IT
|
||||
|
||||
# --------------------------------------------
|
||||
# REQUIRED: IMAGE LIBRARY
|
||||
# This should be gd or imagick
|
||||
# --------------------------------------------
|
||||
IMAGE_LIB=gd
|
||||
|
||||
|
||||
# --------------------------------------------
|
||||
# OPTIONAL: AWS SETTINGS
|
||||
# --------------------------------------------
|
||||
AWS_SECRET_ACCESS_KEY=null
|
||||
AWS_ACCESS_KEY_ID=null
|
||||
AWS_DEFAULT_REGION=null
|
||||
AWS_BUCKET=null
|
||||
AWS_BUCKET_ROOT=null
|
||||
AWS_URL=null
|
||||
|
||||
|
||||
# --------------------------------------------
|
||||
# OPTIONAL: CACHE SETTINGS
|
||||
# --------------------------------------------
|
||||
CACHE_DRIVER=file
|
||||
SESSION_DRIVER=file
|
||||
QUEUE_DRIVER=sync
|
||||
|
||||
|
||||
# --------------------------------------------
|
||||
# OPTIONAL: SESSION SETTINGS
|
||||
# --------------------------------------------
|
||||
SESSION_LIFETIME=12000
|
||||
EXPIRE_ON_CLOSE=false
|
||||
ENCRYPT=false
|
||||
COOKIE_NAME=snipeittest_session
|
||||
COOKIE_DOMAIN=null
|
||||
SECURE_COOKIES=false
|
||||
|
||||
|
||||
# --------------------------------------------
|
||||
# OPTIONAL: APP LOG FORMAT
|
||||
# --------------------------------------------
|
||||
LOG_CHANNEL=single
|
||||
LOG_LEVEL=debug
|
19
.env.testing.example
Normal file
19
.env.testing.example
Normal file
|
@ -0,0 +1,19 @@
|
|||
# --------------------------------------------
|
||||
# REQUIRED: BASIC APP SETTINGS
|
||||
# --------------------------------------------
|
||||
APP_ENV=testing
|
||||
APP_DEBUG=true
|
||||
APP_KEY=base64:glJpcM7BYwWiBggp3SQ/+NlRkqsBQMaGEOjemXqJzOU=
|
||||
APP_URL=http://localhost:8000
|
||||
APP_TIMEZONE='UTC'
|
||||
APP_LOCALE=en
|
||||
|
||||
# --------------------------------------------
|
||||
# REQUIRED: DATABASE SETTINGS
|
||||
# --------------------------------------------
|
||||
DB_CONNECTION=mysql
|
||||
DB_HOST=127.0.0.1
|
||||
DB_PORT=3306
|
||||
DB_DATABASE=null
|
||||
DB_USERNAME=null
|
||||
DB_PASSWORD=null
|
21
.github/workflows/crowdin-upload.yml
vendored
Normal file
21
.github/workflows/crowdin-upload.yml
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
name: Crowdin Action
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ develop ]
|
||||
|
||||
jobs:
|
||||
upload-sources-to-crowdin:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Crowdin push
|
||||
uses: crowdin/github-action@v1
|
||||
with:
|
||||
upload_sources: true
|
||||
upload_translations: false
|
||||
download_translations: false
|
||||
project_id: ${{ secrets.CROWDIN_PROJECT_ID }}
|
||||
token: ${{ secrets.CROWDIN_PERSONAL_TOKEN }}
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -3,6 +3,7 @@
|
|||
.env
|
||||
.env.dusk.*
|
||||
!.env.dusk.example
|
||||
.env.testing
|
||||
phpstan.neon
|
||||
.idea
|
||||
/bin/
|
||||
|
|
|
@ -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-312-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-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)
|
||||
|
||||
## Snipe-IT - Open Source Asset Management System
|
||||
|
||||
|
@ -140,7 +140,7 @@ Thanks goes to all of these wonderful people ([emoji key](https://github.com/ken
|
|||
| [<img src="https://avatars.githubusercontent.com/u/97299851?v=4" width="110px;"/><br /><sub>Christian Weirich</sub>](https://github.com/chrisweirich)<br />[💻](https://github.com/snipe/snipe-it/commits?author=chrisweirich "Code") | [<img src="https://avatars.githubusercontent.com/u/1294403?v=4" width="110px;"/><br /><sub>denzfarid</sub>](https://github.com/denzfarid)<br /> | [<img src="https://avatars.githubusercontent.com/u/94018771?v=4" width="110px;"/><br /><sub>ntbutler-nbcs</sub>](https://github.com/ntbutler-nbcs)<br />[💻](https://github.com/snipe/snipe-it/commits?author=ntbutler-nbcs "Code") | [<img src="https://avatars.githubusercontent.com/u/172697?v=4" width="110px;"/><br /><sub>Naveen</sub>](https://naveensrinivasan.dev)<br />[💻](https://github.com/snipe/snipe-it/commits?author=naveensrinivasan "Code") | [<img src="https://avatars.githubusercontent.com/u/55674383?v=4" width="110px;"/><br /><sub>Mike Roquemore</sub>](https://github.com/mikeroq)<br />[💻](https://github.com/snipe/snipe-it/commits?author=mikeroq "Code") | [<img src="https://avatars.githubusercontent.com/u/7991086?v=4" width="110px;"/><br /><sub>Daniel Reeder</sub>](https://github.com/reederda)<br />[🌍](#translation-reederda "Translation") [🌍](#translation-reederda "Translation") [💻](https://github.com/snipe/snipe-it/commits?author=reederda "Code") | [<img src="https://avatars.githubusercontent.com/u/109422491?v=4" width="110px;"/><br /><sub>vickyjaura183</sub>](https://github.com/vickyjaura183)<br />[💻](https://github.com/snipe/snipe-it/commits?author=vickyjaura183 "Code") |
|
||||
| [<img src="https://avatars.githubusercontent.com/u/32363424?v=4" width="110px;"/><br /><sub>Peace</sub>](https://github.com/julian-piehl)<br />[💻](https://github.com/snipe/snipe-it/commits?author=julian-piehl "Code") | [<img src="https://avatars.githubusercontent.com/u/231528?v=4" width="110px;"/><br /><sub>Kyle Gordon</sub>](https://github.com/kylegordon)<br />[💻](https://github.com/snipe/snipe-it/commits?author=kylegordon "Code") | [<img src="https://avatars.githubusercontent.com/u/53009155?v=4" width="110px;"/><br /><sub>Katharina Drexel</sub>](http://www.bfh.ch)<br />[💻](https://github.com/snipe/snipe-it/commits?author=sunflowerbofh "Code") | [<img src="https://avatars.githubusercontent.com/u/1931963?v=4" width="110px;"/><br /><sub>David Sferruzza</sub>](https://david.sferruzza.fr/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=dsferruzza "Code") | [<img src="https://avatars.githubusercontent.com/u/19511639?v=4" width="110px;"/><br /><sub>Rick Nelson</sub>](https://github.com/rnelsonee)<br />[💻](https://github.com/snipe/snipe-it/commits?author=rnelsonee "Code") | [<img src="https://avatars.githubusercontent.com/u/94169344?v=4" width="110px;"/><br /><sub>BasO12</sub>](https://github.com/BasO12)<br />[💻](https://github.com/snipe/snipe-it/commits?author=BasO12 "Code") | [<img src="https://avatars.githubusercontent.com/u/111710123?v=4" width="110px;"/><br /><sub>Vautia</sub>](https://github.com/Vautia)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Vautia "Code") |
|
||||
| [<img src="https://avatars.githubusercontent.com/u/28321?v=4" width="110px;"/><br /><sub>Chris Hartjes</sub>](http://www.littlehart.net/atthekeyboard)<br />[💻](https://github.com/snipe/snipe-it/commits?author=chartjes "Code") | [<img src="https://avatars.githubusercontent.com/u/2404584?v=4" width="110px;"/><br /><sub>geo-chen</sub>](https://github.com/geo-chen)<br />[💻](https://github.com/snipe/snipe-it/commits?author=geo-chen "Code") | [<img src="https://avatars.githubusercontent.com/u/6006620?v=4" width="110px;"/><br /><sub>Phan Nguyen</sub>](https://github.com/nh314)<br />[💻](https://github.com/snipe/snipe-it/commits?author=nh314 "Code") | [<img src="https://avatars.githubusercontent.com/u/115993812?v=4" width="110px;"/><br /><sub>Iisakki Jaakkola</sub>](https://github.com/StarlessNights)<br />[💻](https://github.com/snipe/snipe-it/commits?author=StarlessNights "Code") | [<img src="https://avatars.githubusercontent.com/u/22633385?v=4" width="110px;"/><br /><sub>Ikko Ashimine</sub>](https://bandism.net/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=eltociear "Code") | [<img src="https://avatars.githubusercontent.com/u/56871540?v=4" width="110px;"/><br /><sub>Lukas Fehling</sub>](https://github.com/lukasfehling)<br />[💻](https://github.com/snipe/snipe-it/commits?author=lukasfehling "Code") | [<img src="https://avatars.githubusercontent.com/u/1975990?v=4" width="110px;"/><br /><sub>Fernando Almeida</sub>](https://github.com/fernando-almeida)<br />[💻](https://github.com/snipe/snipe-it/commits?author=fernando-almeida "Code") |
|
||||
| [<img src="https://avatars.githubusercontent.com/u/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/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") |
|
||||
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
||||
|
||||
This project follows the [all-contributors](https://github.com/kentcdodds/all-contributors) specification. Contributions of any kind welcome!
|
||||
|
|
50
TESTING.md
50
TESTING.md
|
@ -1,45 +1,23 @@
|
|||
# Using the Test Suite
|
||||
# Running the Test Suite
|
||||
|
||||
This document is targeted at developers looking to make modifications to
|
||||
this application's code base and want to run the existing test suite.
|
||||
This document is targeted at developers looking to make modifications to this application's code base and want to run the existing test suite.
|
||||
|
||||
Before starting, follow the [instructions](README.md#installation) for installing the application locally and ensure you can load it in a browser properly.
|
||||
|
||||
## Setup
|
||||
## Unit and Feature Tests
|
||||
|
||||
Follow the instructions for installing the application locally,
|
||||
making sure to have also run the [database migrations](link to db migrations).
|
||||
Before attempting to run the test suite copy the example environment file for tests and update the values to match your environment:
|
||||
|
||||
`cp .env.testing.example .env.testing`
|
||||
> Since the data in the database is flushed after each test it is recommended you create a separate mysql database for specifically for tests
|
||||
|
||||
## Unit Tests
|
||||
Now you are ready to run the entire test suite from your terminal:
|
||||
|
||||
The application will use values in the `.env.testing` file located
|
||||
in the root directory to override the
|
||||
default settings and/or other values that exist in your `.env` files.
|
||||
`php artisan test`
|
||||
|
||||
Make sure to modify the section in `.env.testing` that has the
|
||||
database settings. In the example below, it is connecting to the
|
||||
[MariaDB](link-to-maria-db) server that is used if you install the
|
||||
application using [Docker](https://docker.com).
|
||||
To run individual test files, you can pass the path to the test that you want to run:
|
||||
|
||||
```dotenv
|
||||
# --------------------------------------------
|
||||
# REQUIRED: DATABASE SETTINGS
|
||||
# --------------------------------------------
|
||||
DB_CONNECTION=mysql
|
||||
DB_HOST=127.0.0.1
|
||||
DB_DATABASE=snipeit
|
||||
DB_USERNAME=root
|
||||
DB_PASSWORD=changeme1234
|
||||
```
|
||||
|
||||
To run the entire unit test suite, use the following command from your terminal:
|
||||
|
||||
`php artisan test --env=testing`
|
||||
|
||||
To run individual test files, you can pass the path to the test that
|
||||
you want to run.
|
||||
|
||||
`php artisan test --env=testing tests/Unit/AccessoryTest.php`
|
||||
`php artisan test tests/Unit/AccessoryTest.php`
|
||||
|
||||
## Browser Tests
|
||||
|
||||
|
@ -52,11 +30,9 @@ Before attempting to run Dusk tests copy the example environment file for Dusk a
|
|||
|
||||
**Important**: Dusk tests cannot be run using an in-memory SQLite database. Additionally, the Dusk test suite uses the `DatabaseMigrations` trait which will leave the database in a fresh state after running. Therefore, it is recommended that you create a test database and point `DB_DATABASE` in `.env.dusk.local` to it.
|
||||
|
||||
### Test Setup
|
||||
### Running Browser Tests
|
||||
|
||||
Your application needs to be configured and up and running in order for the browser
|
||||
tests to actually run. When running the tests locally, you can start the application
|
||||
using the following command:
|
||||
Your application needs to be configured and up and running in order for the browser tests to actually run. When running the tests locally, you can start the application using the following command:
|
||||
|
||||
`php artisan serve`
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ class CheckoutLicenseToAllUsers extends Command
|
|||
return false;
|
||||
}
|
||||
|
||||
$users = User::whereNull('deleted_at')->with('licenses')->get();
|
||||
$users = User::whereNull('deleted_at')->where('autoassign_licenses', '==', 1)->with('licenses')->get();
|
||||
|
||||
if ($users->count() > $license->getAvailSeatsCountAttribute()) {
|
||||
$this->info('You do not have enough free seats to complete this task, so we will check out as many as we can. ');
|
||||
|
|
|
@ -6,6 +6,7 @@ use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
|
|||
use App\Helpers\Helper;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Illuminate\Auth\AuthenticationException;
|
||||
use ArieTimmerman\Laravel\SCIMServer\Exceptions\SCIMException;
|
||||
use Log;
|
||||
use Throwable;
|
||||
use JsonException;
|
||||
|
@ -28,6 +29,7 @@ class Handler extends ExceptionHandler
|
|||
\Intervention\Image\Exception\NotSupportedException::class,
|
||||
\League\OAuth2\Server\Exception\OAuthServerException::class,
|
||||
JsonException::class,
|
||||
SCIMException::class, //these generally don't need to be reported
|
||||
];
|
||||
|
||||
/**
|
||||
|
@ -53,7 +55,7 @@ class Handler extends ExceptionHandler
|
|||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Exception $e
|
||||
* @return \Illuminate\Http\Response
|
||||
* @return \Illuminate\Http\JsonResponse|\Illuminate\Http\RedirectResponse|\Illuminate\Http\Response
|
||||
*/
|
||||
public function render($request, Throwable $e)
|
||||
{
|
||||
|
@ -70,6 +72,9 @@ class Handler extends ExceptionHandler
|
|||
return response()->json(Helper::formatStandardApiResponse('error', null, 'invalid JSON'), 422);
|
||||
}
|
||||
|
||||
if ($e instanceof SCIMException) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, 'invalid SCIM Request'), 400);
|
||||
}
|
||||
|
||||
// Handle Ajax requests that fail because the model doesn't exist
|
||||
if ($request->ajax() || $request->wantsJson()) {
|
||||
|
@ -113,8 +118,8 @@ class Handler extends ExceptionHandler
|
|||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Illuminate\Auth\AuthenticationException $exception
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
* @return \Illuminate\Http\JsonResponse|\Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
protected function unauthenticated($request, AuthenticationException $exception)
|
||||
{
|
||||
if ($request->expectsJson()) {
|
||||
|
|
|
@ -26,7 +26,10 @@ class AccessoriesController extends Controller
|
|||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
$this->authorize('view', Accessory::class);
|
||||
if ($request->user()->cannot('reports.view')) {
|
||||
$this->authorize('view', Accessory::class);
|
||||
}
|
||||
|
||||
|
||||
// This array is what determines which fields should be allowed to be sorted on ON the table itself, no relations
|
||||
// Relations will be handled in query scopes a little further down.
|
||||
|
|
|
@ -101,6 +101,7 @@ class AssetsController extends Controller
|
|||
'checkin_counter',
|
||||
'requests_counter',
|
||||
'byod',
|
||||
'asset_eol_date',
|
||||
];
|
||||
|
||||
$filter = [];
|
||||
|
@ -128,7 +129,6 @@ class AssetsController extends Controller
|
|||
// They are also used by the individual searches on detail pages like
|
||||
// locations, etc.
|
||||
|
||||
|
||||
// Search custom fields by column name
|
||||
foreach ($all_custom_fields as $field) {
|
||||
if ($request->filled($field->db_column_name())) {
|
||||
|
@ -136,7 +136,6 @@ class AssetsController extends Controller
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
if ($request->filled('status_id')) {
|
||||
$assets->where('assets.status_id', '=', $request->input('status_id'));
|
||||
}
|
||||
|
@ -173,6 +172,10 @@ class AssetsController extends Controller
|
|||
$assets->where('assets.supplier_id', '=', $request->input('supplier_id'));
|
||||
}
|
||||
|
||||
if ($request->filled('asset_eol_date')) {
|
||||
$assets->where('assets.asset_eol_date', '=', $request->input('asset_eol_date'));
|
||||
}
|
||||
|
||||
if (($request->filled('assigned_to')) && ($request->filled('assigned_type'))) {
|
||||
$assets->where('assets.assigned_to', '=', $request->input('assigned_to'))
|
||||
->where('assets.assigned_type', '=', $request->input('assigned_type'));
|
||||
|
|
|
@ -24,10 +24,50 @@ class CategoriesController extends Controller
|
|||
public function index(Request $request)
|
||||
{
|
||||
$this->authorize('view', Category::class);
|
||||
$allowed_columns = ['id', 'name', 'category_type', 'category_type', 'use_default_eula', 'eula_text', 'require_acceptance', 'checkin_email', 'assets_count', 'accessories_count', 'consumables_count', 'components_count', 'licenses_count', 'image'];
|
||||
$allowed_columns = [
|
||||
'id',
|
||||
'name',
|
||||
'category_type',
|
||||
'category_type',
|
||||
'use_default_eula',
|
||||
'eula_text',
|
||||
'require_acceptance',
|
||||
'checkin_email',
|
||||
'assets_count',
|
||||
'accessories_count',
|
||||
'consumables_count',
|
||||
'components_count',
|
||||
'licenses_count',
|
||||
'image',
|
||||
];
|
||||
|
||||
$categories = Category::select([
|
||||
'id',
|
||||
'created_at',
|
||||
'updated_at',
|
||||
'name', 'category_type',
|
||||
'use_default_eula',
|
||||
'eula_text',
|
||||
'require_acceptance',
|
||||
'checkin_email',
|
||||
'image'
|
||||
])->withCount('accessories as accessories_count', 'consumables as consumables_count', 'components as components_count', 'licenses as licenses_count');
|
||||
|
||||
|
||||
/*
|
||||
* This checks to see if we should override the Admin Setting to show archived assets in list.
|
||||
* We don't currently use it within the Snipe-IT GUI, but will be useful for API integrations where they
|
||||
* may actually need to fetch assets that are archived.
|
||||
*
|
||||
* @see \App\Models\Category::showableAssets()
|
||||
*/
|
||||
if ($request->input('archived')=='true') {
|
||||
$categories = $categories->withCount('assets as assets_count');
|
||||
} else {
|
||||
$categories = $categories->withCount('showableAssets as assets_count');
|
||||
}
|
||||
|
||||
|
||||
$categories = Category::select(['id', 'created_at', 'updated_at', 'name', 'category_type', 'use_default_eula', 'eula_text', 'require_acceptance', 'checkin_email', 'image'])
|
||||
->withCount('assets as assets_count', 'accessories as accessories_count', 'consumables as consumables_count', 'components as components_count', 'licenses as licenses_count');
|
||||
|
||||
if ($request->filled('search')) {
|
||||
$categories = $categories->TextSearch($request->input('search'));
|
||||
|
|
|
@ -126,7 +126,14 @@ class ImportController extends Controller
|
|||
}
|
||||
$file_name = date('Y-m-d-his').'-'.$fixed_filename;
|
||||
$import->file_path = $file_name;
|
||||
$import->filesize = null;
|
||||
|
||||
if (!file_exists($path.'/'.$file_name)) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('general.file_not_found')), 500);
|
||||
}
|
||||
|
||||
$import->filesize = filesize($path.'/'.$file_name);
|
||||
|
||||
$import->save();
|
||||
$results[] = $import;
|
||||
}
|
||||
|
|
|
@ -57,8 +57,12 @@ class ReportsController extends Controller
|
|||
$sort = in_array($request->input('sort'), $allowed_columns) ? e($request->input('sort')) : 'created_at';
|
||||
$order = ($request->input('order') == 'asc') ? 'asc' : 'desc';
|
||||
$offset = request('offset', 0);
|
||||
$limit = request('limit', 50);
|
||||
$total = $actionlogs->count();
|
||||
|
||||
// Check to make sure the limit is not higher than the max allowed
|
||||
((config('app.max_results') >= $request->input('limit')) && ($request->filled('limit'))) ? $limit = $request->input('limit') : $limit = config('app.max_results');
|
||||
|
||||
|
||||
$actionlogs = $actionlogs->orderBy($sort, $order)->skip($offset)->take($limit)->get();
|
||||
|
||||
return response()->json((new ActionlogsTransformer)->transformActionlogs($actionlogs, $total), 200, ['Content-Type' => 'application/json;charset=utf8'], JSON_UNESCAPED_UNICODE);
|
||||
|
|
|
@ -271,7 +271,7 @@ class SettingsController extends Controller
|
|||
$headers = ['ContentType' => 'application/zip'];
|
||||
return Storage::download($path.'/'.$file, $file, $headers);
|
||||
} else {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, 'File not found'));
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('general.file_not_found')));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -196,6 +196,7 @@ class StatuslabelsController extends Controller
|
|||
{
|
||||
$this->authorize('view', Statuslabel::class);
|
||||
$statuslabels = Statuslabel::withCount('assets')->get();
|
||||
$total = Array();
|
||||
|
||||
foreach ($statuslabels as $statuslabel) {
|
||||
|
||||
|
|
|
@ -69,6 +69,7 @@ class UsersController extends Controller
|
|||
'users.ldap_import',
|
||||
'users.start_date',
|
||||
'users.end_date',
|
||||
'users.vip',
|
||||
|
||||
])->with('manager', 'groups', 'userloc', 'company', 'department', 'assets', 'licenses', 'accessories', 'consumables', 'createdBy',)
|
||||
->withCount('assets as assets_count', 'licenses as licenses_count', 'accessories as accessories_count', 'consumables as consumables_count');
|
||||
|
@ -149,6 +150,10 @@ class UsersController extends Controller
|
|||
$users = $users->where('remote', '=', $request->input('remote'));
|
||||
}
|
||||
|
||||
if ($request->filled('vip')) {
|
||||
$users = $users->where('vip', '=', $request->input('vip'));
|
||||
}
|
||||
|
||||
if ($request->filled('two_factor_enrolled')) {
|
||||
$users = $users->where('two_factor_enrolled', '=', $request->input('two_factor_enrolled'));
|
||||
}
|
||||
|
@ -246,6 +251,7 @@ class UsersController extends Controller
|
|||
'two_factor_optin',
|
||||
'two_factor_enrolled',
|
||||
'remote',
|
||||
'vip',
|
||||
'start_date',
|
||||
'end_date',
|
||||
];
|
||||
|
@ -286,9 +292,11 @@ class UsersController extends Controller
|
|||
$users = Company::scopeCompanyables($users);
|
||||
|
||||
if ($request->filled('search')) {
|
||||
$users = $users->SimpleNameSearch($request->get('search'))
|
||||
->orWhere('username', 'LIKE', '%'.$request->get('search').'%')
|
||||
->orWhere('employee_num', 'LIKE', '%'.$request->get('search').'%');
|
||||
$users = $users->where(function ($query) use ($request) {
|
||||
$query->SimpleNameSearch($request->get('search'))
|
||||
->orWhere('username', 'LIKE', '%'.$request->get('search').'%')
|
||||
->orWhere('employee_num', 'LIKE', '%'.$request->get('search').'%');
|
||||
});
|
||||
}
|
||||
|
||||
$users = $users->orderBy('last_name', 'asc')->orderBy('first_name', 'asc');
|
||||
|
|
|
@ -27,7 +27,7 @@ class AssetCheckoutController extends Controller
|
|||
public function create($assetId)
|
||||
{
|
||||
// Check if the asset exists
|
||||
if (is_null($asset = Asset::find(e($assetId)))) {
|
||||
if (is_null($asset = Asset::with('company')->find(e($assetId)))) {
|
||||
return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.does_not_exist'));
|
||||
}
|
||||
|
||||
|
|
|
@ -142,6 +142,7 @@ class AssetsController extends Controller
|
|||
$asset->warranty_months = request('warranty_months', null);
|
||||
$asset->purchase_cost = Helper::ParseCurrency($request->get('purchase_cost'));
|
||||
$asset->purchase_date = request('purchase_date', null);
|
||||
$asset->asset_eol_date = request('asset_eol_date', null);
|
||||
$asset->assigned_to = request('assigned_to', null);
|
||||
$asset->supplier_id = request('supplier_id', null);
|
||||
$asset->requestable = request('requestable', 0);
|
||||
|
@ -312,6 +313,8 @@ class AssetsController extends Controller
|
|||
$asset->status_id = $request->input('status_id', null);
|
||||
$asset->warranty_months = $request->input('warranty_months', null);
|
||||
$asset->purchase_cost = Helper::ParseCurrency($request->input('purchase_cost', null));
|
||||
$asset->asset_eol_date = request('asset_eol_date', null);
|
||||
|
||||
$asset->purchase_date = $request->input('purchase_date', null);
|
||||
$asset->supplier_id = $request->input('supplier_id', null);
|
||||
$asset->expected_checkin = $request->input('expected_checkin', null);
|
||||
|
|
|
@ -288,7 +288,8 @@ class BulkAssetsController extends Controller
|
|||
foreach ($asset_ids as $asset_id) {
|
||||
$asset = Asset::findOrFail($asset_id);
|
||||
$this->authorize('checkout', $asset);
|
||||
$error = $asset->checkOut($target, $admin, $checkout_at, $expected_checkin, e($request->get('note')), null);
|
||||
|
||||
$error = $asset->checkOut($target, $admin, $checkout_at, $expected_checkin, e($request->get('note')), $asset->name, null);
|
||||
|
||||
if ($target->location_id != '') {
|
||||
$asset->location_id = $target->location_id;
|
||||
|
|
|
@ -59,6 +59,12 @@ class LicenseCheckinController extends Controller
|
|||
}
|
||||
|
||||
$license = License::find($licenseSeat->license_id);
|
||||
|
||||
// LicenseSeat is not assigned, it can't be checked in
|
||||
if (is_null($licenseSeat->assigned_to) && is_null($licenseSeat->asset_id)) {
|
||||
return redirect()->route('licenses.index')->with('error', trans('admin/licenses/message.checkin.error'));
|
||||
}
|
||||
|
||||
$this->authorize('checkout', $license);
|
||||
|
||||
if (! $license->reassignable) {
|
||||
|
|
|
@ -227,6 +227,36 @@ class LocationsController extends Controller
|
|||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a view that presents a form to clone a location.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param int $locationId
|
||||
* @since [v6.0.14]
|
||||
* @return View
|
||||
*/
|
||||
public function getClone($locationId = null)
|
||||
{
|
||||
$this->authorize('create', Location::class);
|
||||
|
||||
// Check if the asset exists
|
||||
if (is_null($location_to_clone = Location::find($locationId))) {
|
||||
// Redirect to the asset management page
|
||||
return redirect()->route('licenses.index')->with('error', trans('admin/locations/message.does_not_exist'));
|
||||
}
|
||||
|
||||
$location = clone $location_to_clone;
|
||||
|
||||
// unset these values
|
||||
$location->id = null;
|
||||
$location->image = null;
|
||||
|
||||
return view('locations/edit')
|
||||
->with('item', $location);
|
||||
}
|
||||
|
||||
|
||||
public function print_all_assigned($id)
|
||||
{
|
||||
if ($location = Location::where('id', $id)->first()) {
|
||||
|
|
|
@ -51,9 +51,8 @@ class ReportsController extends Controller
|
|||
public function getAccessoryReport()
|
||||
{
|
||||
$this->authorize('reports.view');
|
||||
$accessories = Accessory::orderBy('created_at', 'DESC')->with('company')->get();
|
||||
|
||||
return view('reports/accessories', compact('accessories'));
|
||||
return view('reports/accessories');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -285,7 +284,7 @@ class ReportsController extends Controller
|
|||
|
||||
$row = [
|
||||
$actionlog->created_at,
|
||||
($actionlog->user) ? e($actionlog->user->getFullNameAttribute()) : '',
|
||||
($actionlog->admin) ? e($actionlog->admin->getFullNameAttribute()) : '',
|
||||
$actionlog->present()->actionType(),
|
||||
e($actionlog->itemType()),
|
||||
($actionlog->itemType() == 'user') ? $actionlog->filename : $item_name,
|
||||
|
|
|
@ -65,18 +65,27 @@ class SettingsController extends Controller
|
|||
$start_settings['db_error'] = $e->getMessage();
|
||||
}
|
||||
|
||||
$protocol = array_key_exists('HTTPS', $_SERVER) && ('on' == $_SERVER['HTTPS']) ? 'https://' : 'http://';
|
||||
if (array_key_exists("HTTP_X_FORWARDED_PROTO", $_SERVER)) {
|
||||
$protocol = $_SERVER["HTTP_X_FORWARDED_PROTO"] . "://";
|
||||
} elseif (array_key_exists('HTTPS', $_SERVER) && ('on' == $_SERVER['HTTPS'])) {
|
||||
$protocol = "https://";
|
||||
} else {
|
||||
$protocol = "http://";
|
||||
}
|
||||
|
||||
$host = array_key_exists('SERVER_NAME', $_SERVER) ? $_SERVER['SERVER_NAME'] : null;
|
||||
$port = array_key_exists('SERVER_PORT', $_SERVER) ? $_SERVER['SERVER_PORT'] : null;
|
||||
if (('http://' === $protocol && '80' != $port) || ('https://' === $protocol && '443' != $port)) {
|
||||
$host .= ':'.$port;
|
||||
if (array_key_exists("HTTP_X_FORWARDED_HOST", $_SERVER)) {
|
||||
$host = $_SERVER["HTTP_X_FORWARDED_HOST"];
|
||||
} else {
|
||||
$host = array_key_exists('SERVER_NAME', $_SERVER) ? $_SERVER['SERVER_NAME'] : null;
|
||||
$port = array_key_exists('SERVER_PORT', $_SERVER) ? $_SERVER['SERVER_PORT'] : null;
|
||||
if (('http://' === $protocol && '80' != $port) || ('https://' === $protocol && '443' != $port)) {
|
||||
$host .= ':'.$port;
|
||||
}
|
||||
}
|
||||
$pageURL = $protocol.$host.$_SERVER['REQUEST_URI'];
|
||||
|
||||
$start_settings['url_valid'] = (url('/').'/setup' === $pageURL);
|
||||
|
||||
$start_settings['url_config'] = url('/');
|
||||
$start_settings['url_config'] = url('/').'/setup';
|
||||
$start_settings['url_valid'] = ($start_settings['url_config'] === $pageURL);
|
||||
$start_settings['real_url'] = $pageURL;
|
||||
$start_settings['php_version_min'] = true;
|
||||
|
||||
|
@ -111,17 +120,17 @@ class SettingsController extends Controller
|
|||
$start_settings['prod'] = true;
|
||||
}
|
||||
|
||||
$start_settings['owner'] = '';
|
||||
|
||||
if (function_exists('posix_getpwuid')) { // Probably Linux
|
||||
$owner = posix_getpwuid(fileowner($_SERVER['SCRIPT_FILENAME']));
|
||||
$start_settings['owner'] = $owner['name'];
|
||||
} else { // Windows
|
||||
// TODO: Is there a way of knowing if a windows user has elevated permissions
|
||||
// This just gets the user name, which likely isn't 'root'
|
||||
// $start_settings['owner'] = getenv('USERNAME');
|
||||
$start_settings['owner'] = '';
|
||||
// This *should* be an array, but we've seen this return a bool in some chrooted environments
|
||||
if (is_array($owner)) {
|
||||
$start_settings['owner'] = $owner['name'];
|
||||
}
|
||||
}
|
||||
|
||||
if (('root' === $start_settings['owner']) || ('0' === $start_settings['owner'])) {
|
||||
if (($start_settings['owner'] === 'root') || ($start_settings['owner'] === '0')) {
|
||||
$start_settings['owner_is_admin'] = true;
|
||||
} else {
|
||||
$start_settings['owner_is_admin'] = false;
|
||||
|
|
|
@ -121,6 +121,7 @@ class UsersController extends Controller
|
|||
$user->created_by = Auth::user()->id;
|
||||
$user->start_date = $request->input('start_date', null);
|
||||
$user->end_date = $request->input('end_date', null);
|
||||
$user->autoassign_licenses= $request->input('autoassign_licenses', 1);
|
||||
|
||||
// Strip out the superuser permission if the user isn't a superadmin
|
||||
$permissions_array = $request->input('permission');
|
||||
|
@ -271,9 +272,11 @@ class UsersController extends Controller
|
|||
$user->activated = $request->input('activated', 0);
|
||||
$user->zip = $request->input('zip', null);
|
||||
$user->remote = $request->input('remote', 0);
|
||||
$user->vip = $request->input('vip', 0);
|
||||
$user->website = $request->input('website', null);
|
||||
$user->start_date = $request->input('start_date', null);
|
||||
$user->end_date = $request->input('end_date', null);
|
||||
$user->autoassign_licenses = $request->input('autoassign_licenses', 1);
|
||||
|
||||
// Update the location of any assets checked out to this user
|
||||
Asset::where('assigned_type', User::class)
|
||||
|
|
|
@ -7,7 +7,9 @@ use enshrined\svgSanitize\Sanitizer;
|
|||
use Intervention\Image\Facades\Image;
|
||||
use App\Http\Traits\ConvertsBase64ToFiles;
|
||||
use Illuminate\Http\UploadedFile;
|
||||
use Storage;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Intervention\Image\Exception\NotReadableException;
|
||||
|
||||
|
||||
class ImageUploadRequest extends Request
|
||||
{
|
||||
|
@ -106,10 +108,18 @@ class ImageUploadRequest extends Request
|
|||
\Log::debug('Not an SVG or webp - resize');
|
||||
\Log::debug('Trying to upload to: '.$path.'/'.$file_name);
|
||||
|
||||
$upload = Image::make($image->getRealPath())->resize(null, $w, function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
});
|
||||
try {
|
||||
$upload = Image::make($image->getRealPath())->resize(null, $w, function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
});
|
||||
} catch(NotReadableException $e) {
|
||||
\Log::debug($e);
|
||||
$validator = \Validator::make([], []);
|
||||
$validator->errors()->add($form_fieldname, trans('general.unaccepted_image_type', ['mimetype' => $image->getClientMimeType()]));
|
||||
|
||||
throw new \Illuminate\Validation\ValidationException($validator);
|
||||
}
|
||||
|
||||
// This requires a string instead of an object, so we use ($string)
|
||||
Storage::disk('public')->put($path.'/'.$file_name, (string) $upload->encode());
|
||||
|
|
|
@ -38,7 +38,8 @@ class AssetsTransformer
|
|||
'byod' => ($asset->byod ? true : false),
|
||||
|
||||
'model_number' => (($asset->model) && ($asset->model->model_number)) ? e($asset->model->model_number) : null,
|
||||
'eol' => ($asset->purchase_date != '') ? Helper::getFormattedDateObject($asset->present()->eol_date(), 'date') : null,
|
||||
'eol' => ($asset->model->eol != '') ? $asset->model->eol : null,
|
||||
'asset_eol_date' => ($asset->asset_eol_date != '') ? Helper::getFormattedDateObject($asset->asset_eol_date, 'date') : null,
|
||||
'status_label' => ($asset->assetstatus) ? [
|
||||
'id' => (int) $asset->assetstatus->id,
|
||||
'name'=> e($asset->assetstatus->name),
|
||||
|
|
|
@ -4,7 +4,7 @@ namespace App\Http\Transformers;
|
|||
|
||||
use App\Helpers\Helper;
|
||||
use App\Models\Location;
|
||||
use Gate;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
|
@ -63,6 +63,7 @@ class LocationsTransformer
|
|||
$permissions_array['available_actions'] = [
|
||||
'update' => Gate::allows('update', Location::class) ? true : false,
|
||||
'delete' => $location->isDeletable(),
|
||||
'clone' => (Gate::allows('create', Location::class) && ($location->deleted_at == '')),
|
||||
];
|
||||
|
||||
$array += $permissions_array;
|
||||
|
|
|
@ -36,6 +36,7 @@ class UsersTransformer
|
|||
'name'=> e($user->manager->first_name).' '.e($user->manager->last_name),
|
||||
] : null,
|
||||
'jobtitle' => ($user->jobtitle) ? e($user->jobtitle) : null,
|
||||
'vip' => ($user->vip == '1') ? true : false,
|
||||
'phone' => ($user->phone) ? e($user->phone) : null,
|
||||
'website' => ($user->website) ? e($user->website) : null,
|
||||
'address' => ($user->address) ? e($user->address) : null,
|
||||
|
|
|
@ -76,10 +76,12 @@ class AssetImporter extends ItemImporter
|
|||
}
|
||||
$this->item['notes'] = $this->findCsvMatch($row, 'asset_notes');
|
||||
$this->item['image'] = $this->findCsvMatch($row, 'image');
|
||||
$this->item['requestable'] = $this->fetchHumanBoolean($this->findCsvMatch($row, 'requestable'));
|
||||
$asset->requestable = $this->fetchHumanBoolean($this->findCsvMatch($row, 'requestable'));
|
||||
$this->item['requestable'] = ($this->fetchHumanBoolean($this->findCsvMatch($row, 'requestable')) == 1) ? '1' : 0;
|
||||
$asset->requestable = $this->item['requestable'];
|
||||
$this->item['warranty_months'] = intval($this->findCsvMatch($row, 'warranty_months'));
|
||||
$this->item['model_id'] = $this->createOrFetchAssetModel($row);
|
||||
$this->item['byod'] = ($this->fetchHumanBoolean($this->findCsvMatch($row, 'byod')) == 1) ? '1' : 0;
|
||||
|
||||
|
||||
// If no status ID is found
|
||||
if (! array_key_exists('status_id', $this->item) && ! $editingAsset) {
|
||||
|
@ -135,7 +137,7 @@ class AssetImporter extends ItemImporter
|
|||
//-- user_id is a property of the abstract class Importer, which this class inherits from and it's setted by
|
||||
//-- the class that needs to use it (command importer or GUI importer inside the project).
|
||||
if (isset($target)) {
|
||||
$asset->fresh()->checkOut($target, $this->user_id, date('Y-m-d H:i:s'));
|
||||
$asset->fresh()->checkOut($target, $this->user_id, date('Y-m-d H:i:s'), null, $asset->notes, $asset->name);
|
||||
}
|
||||
|
||||
return;
|
||||
|
|
|
@ -74,7 +74,7 @@ class ItemImporter extends Importer
|
|||
|
||||
$this->item['purchase_date'] = null;
|
||||
if ($this->findCsvMatch($row, 'purchase_date') != '') {
|
||||
$this->item['purchase_date'] = date('Y-m-d 00:00:01', strtotime($this->findCsvMatch($row, 'purchase_date')));
|
||||
$this->item['purchase_date'] = date('Y-m-d', strtotime($this->findCsvMatch($row, 'purchase_date')));
|
||||
}
|
||||
|
||||
$this->item['last_audit_date'] = null;
|
||||
|
@ -90,7 +90,7 @@ class ItemImporter extends Importer
|
|||
$this->item['qty'] = $this->findCsvMatch($row, 'quantity');
|
||||
$this->item['requestable'] = $this->findCsvMatch($row, 'requestable');
|
||||
$this->item['user_id'] = $this->user_id;
|
||||
$this->item['serial'] = $this->findCsvMatch($row, 'serial number');
|
||||
$this->item['serial'] = $this->findCsvMatch($row, 'serial');
|
||||
// NO need to call this method if we're running the user import.
|
||||
// TODO: Merge these methods.
|
||||
$this->item['checkout_class'] = $this->findCsvMatch($row, 'checkout_class');
|
||||
|
@ -222,11 +222,11 @@ class ItemImporter extends Importer
|
|||
$item = $this->sanitizeItemForStoring($asset_model, $editingModel);
|
||||
$item['name'] = $asset_model_name;
|
||||
$item['notes'] = $this->findCsvMatch($row, 'model_notes');
|
||||
|
||||
|
||||
if(!empty($asset_modelNumber)){
|
||||
$item['model_number'] = $asset_modelNumber;
|
||||
}
|
||||
|
||||
|
||||
$asset_model->update($item);
|
||||
$asset_model->save();
|
||||
$this->log('Asset Model Updated');
|
||||
|
|
|
@ -58,6 +58,8 @@ class UserImporter extends ItemImporter
|
|||
$this->item['department_id'] = $this->createOrFetchDepartment($this->findCsvMatch($row, 'department'));
|
||||
$this->item['manager_id'] = $this->fetchManager($this->findCsvMatch($row, 'manager_first_name'), $this->findCsvMatch($row, 'manager_last_name'));
|
||||
$this->item['remote'] =($this->fetchHumanBoolean($this->findCsvMatch($row, 'remote')) ==1 ) ? '1' : 0;
|
||||
$this->item['vip'] =($this->fetchHumanBoolean($this->findCsvMatch($row, 'vip')) ==1 ) ? '1' : 0;
|
||||
|
||||
|
||||
$user_department = $this->findCsvMatch($row, 'department');
|
||||
if ($this->shouldUpdateField($user_department)) {
|
||||
|
|
|
@ -36,8 +36,10 @@
|
|||
| name | | |
|
||||
| email | | |
|
||||
| username | | |
|
||||
| address | address | User |
|
||||
| city | city | User |
|
||||
| state | state | User |
|
||||
| country | country | User |
|
||||
| address | address | User |
|
||||
| city | city | User |
|
||||
| state | state | User |
|
||||
| country | country | User |
|
||||
| vip | vip | User |
|
||||
| byod | byod | Asset |
|
||||
|
||||
|
|
|
@ -114,6 +114,7 @@ class Asset extends Depreciable
|
|||
'serial' => 'unique_serial|nullable',
|
||||
'purchase_cost' => 'numeric|nullable|gte:0',
|
||||
'supplier_id' => 'exists:suppliers,id|nullable',
|
||||
'asset_eol_date' => 'date|max:10|min:10|nullable',
|
||||
];
|
||||
|
||||
/**
|
||||
|
@ -143,9 +144,9 @@ class Asset extends Depreciable
|
|||
'last_checkout',
|
||||
'expected_checkin',
|
||||
'byod',
|
||||
'asset_eol_date',
|
||||
'last_audit_date',
|
||||
'next_audit_date',
|
||||
|
||||
];
|
||||
|
||||
use Searchable;
|
||||
|
@ -168,6 +169,7 @@ class Asset extends Depreciable
|
|||
'expected_checkin',
|
||||
'next_audit_date',
|
||||
'last_audit_date',
|
||||
'asset_eol_date',
|
||||
];
|
||||
|
||||
/**
|
||||
|
@ -181,11 +183,19 @@ class Asset extends Depreciable
|
|||
'company' => ['name'],
|
||||
'defaultLoc' => ['name'],
|
||||
'location' => ['name'],
|
||||
'model' => ['name', 'model_number'],
|
||||
'model' => ['name', 'model_number', 'eol'],
|
||||
'model.category' => ['name'],
|
||||
'model.manufacturer' => ['name'],
|
||||
];
|
||||
|
||||
// To properly set the expected checkin as Y-m-d
|
||||
public function setExpectedCheckinAttribute($value)
|
||||
{
|
||||
if ($value == '') {
|
||||
$value = null;
|
||||
}
|
||||
$this->attributes['expected_checkin'] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* This handles the custom field validation for assets
|
||||
|
@ -537,6 +547,28 @@ class Asset extends Depreciable
|
|||
return strtolower(class_basename($this->assigned_type));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This is annoying, but because we don't say "assets" in our route names, we have to make an exception here
|
||||
* @todo - normalize the route names - API endpoint URLS can stay the same
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v6.1.0]
|
||||
* @return string
|
||||
*/
|
||||
public function targetShowRoute()
|
||||
{
|
||||
$route = str_plural($this->assignedType());
|
||||
if ($route=='assets') {
|
||||
return 'hardware';
|
||||
}
|
||||
|
||||
return $route;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the asset's location based on default RTD location
|
||||
*
|
||||
|
@ -1633,9 +1665,9 @@ class Asset extends Depreciable
|
|||
*/
|
||||
public function scopeOrderManufacturer($query, $order)
|
||||
{
|
||||
return $query->join('models', 'assets.model_id', '=', 'models.id')
|
||||
->join('manufacturers', 'models.manufacturer_id', '=', 'manufacturers.id')
|
||||
->orderBy('manufacturers.name', $order);
|
||||
return $query->join('models as order_asset_model', 'assets.model_id', '=', 'order_asset_model.id')
|
||||
->join('manufacturers as manufacturer_order', 'order_asset_model.manufacturer_id', '=', 'manufacturer_order.id')
|
||||
->orderBy('manufacturer_order.name', $order);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -194,7 +194,25 @@ class Category extends SnipeModel
|
|||
*/
|
||||
public function assets()
|
||||
{
|
||||
return $this->hasManyThrough(\App\Models\Asset::class, \App\Models\AssetModel::class, 'category_id', 'model_id');
|
||||
return $this->hasManyThrough(Asset::class, \App\Models\AssetModel::class, 'category_id', 'model_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Establishes the category -> assets relationship but also takes into consideration
|
||||
* the setting to show archived in lists.
|
||||
*
|
||||
* We could have complicated the assets() method above, but keeping this separate
|
||||
* should give us more flexibility if we need to return actually archived assets
|
||||
* by their category.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v6.1.0]
|
||||
* @see \App\Models\Asset::scopeAssetsForShow()
|
||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||
*/
|
||||
public function showableAssets()
|
||||
{
|
||||
return $this->hasManyThrough(Asset::class, \App\Models\AssetModel::class, 'category_id', 'model_id')->AssetsForShow();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -25,7 +25,10 @@ class CheckoutAcceptance extends Model
|
|||
{
|
||||
// At this point the endpoint is the same for everything.
|
||||
// In the future this may want to be adapted for individual notifications.
|
||||
return Setting::getSettings()->alert_email;
|
||||
$recipients_string = explode(',', Setting::getSettings()->alert_email);
|
||||
$recipients = array_map('trim', $recipients_string);
|
||||
|
||||
return array_filter($recipients);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -16,7 +16,7 @@ class Depreciation extends SnipeModel
|
|||
// Declare the rules for the form validation
|
||||
protected $rules = [
|
||||
'name' => 'required|min:3|max:255|unique:depreciations,name',
|
||||
'months' => 'required|max:3600|integer',
|
||||
'months' => 'required|max:3600|integer|gt:0',
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
|
@ -36,7 +36,6 @@ class License extends Depreciable
|
|||
'purchase_date' => 'datetime',
|
||||
'expiration_date' => 'datetime',
|
||||
'termination_date' => 'datetime',
|
||||
'seats' => 'integer',
|
||||
'category_id' => 'integer',
|
||||
'company_id' => 'integer',
|
||||
];
|
||||
|
@ -368,7 +367,7 @@ class License extends Depreciable
|
|||
*/
|
||||
public function assignedusers()
|
||||
{
|
||||
return $this->belongsToMany(\App\Models\User::class, 'license_seats', 'assigned_to', 'license_id');
|
||||
return $this->belongsToMany(\App\Models\User::class, 'license_seats', 'license_id', 'assigned_to');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -93,8 +93,12 @@ trait Loggable
|
|||
{
|
||||
$settings = Setting::getSettings();
|
||||
$log = new Actionlog;
|
||||
$log->target_type = get_class($target);
|
||||
$log->target_id = $target->id;
|
||||
|
||||
if($target != null){
|
||||
$log->target_type = get_class($target);
|
||||
$log->target_id = $target->id;
|
||||
|
||||
}
|
||||
|
||||
if (static::class == LicenseSeat::class) {
|
||||
$log->item_type = License::class;
|
||||
|
|
|
@ -64,6 +64,7 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
|
|||
'scim_externalid',
|
||||
'avatar',
|
||||
'gravatar',
|
||||
'vip',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
|
@ -71,6 +72,7 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
|
|||
'manager_id' => 'integer',
|
||||
'location_id' => 'integer',
|
||||
'company_id' => 'integer',
|
||||
'vip' => 'boolean',
|
||||
];
|
||||
|
||||
|
||||
|
@ -78,8 +80,8 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
|
|||
'created_at',
|
||||
'updated_at',
|
||||
'deleted_at',
|
||||
'start_date',
|
||||
'end_date',
|
||||
'start_date' => 'date_format:Y-m-d',
|
||||
'end_date' => 'date_format:Y-m-d',
|
||||
];
|
||||
|
||||
|
||||
|
@ -285,7 +287,7 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
|
|||
*/
|
||||
public function assets()
|
||||
{
|
||||
return $this->morphMany(\App\Models\Asset::class, 'assigned', 'assigned_type', 'assigned_to')->withTrashed();
|
||||
return $this->morphMany(\App\Models\Asset::class, 'assigned', 'assigned_type', 'assigned_to')->withTrashed()->orderBy('id');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -313,7 +315,7 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
|
|||
public function accessories()
|
||||
{
|
||||
return $this->belongsToMany(\App\Models\Accessory::class, 'accessories_users', 'assigned_to', 'accessory_id')
|
||||
->withPivot('id', 'created_at', 'note')->withTrashed();
|
||||
->withPivot('id', 'created_at', 'note')->withTrashed()->orderBy('accessory_id');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -163,9 +163,16 @@ class AssetPresenter extends Presenter
|
|||
], [
|
||||
'field' => 'eol',
|
||||
'searchable' => false,
|
||||
'sortable' => false,
|
||||
'sortable' => true,
|
||||
'visible' => false,
|
||||
'title' => trans('general.eol'),
|
||||
],
|
||||
[
|
||||
'field' => 'asset_eol_date',
|
||||
'searchable' => true,
|
||||
'sortable' => true,
|
||||
'visible' => false,
|
||||
'title' => trans('admin/hardware/form.eol_date'),
|
||||
'formatter' => 'dateDisplayFormatter',
|
||||
], [
|
||||
'field' => 'warranty_months',
|
||||
|
|
|
@ -85,6 +85,15 @@ class UserPresenter extends Presenter
|
|||
'visible' => true,
|
||||
'formatter' => 'usersLinkFormatter',
|
||||
],
|
||||
[
|
||||
'field' => 'vip',
|
||||
'searchable' => false,
|
||||
'sortable' => true,
|
||||
'switchable' => true,
|
||||
'title' => trans('admin/users/general.vip_label'),
|
||||
'visible' => false,
|
||||
'formatter' => 'trueFalseFormatter',
|
||||
],
|
||||
[
|
||||
'field' => 'remote',
|
||||
'searchable' => false,
|
||||
|
|
|
@ -61,12 +61,13 @@
|
|||
"nunomaduro/collision": "^5.4",
|
||||
"onelogin/php-saml": "^3.4",
|
||||
"paragonie/constant_time_encoding": "^2.3",
|
||||
"symfony/polyfill-mbstring": "^1.22",
|
||||
"paragonie/sodium_compat": "^1.19",
|
||||
"phpdocumentor/reflection-docblock": "^5.1",
|
||||
"phpspec/prophecy": "^1.10",
|
||||
"pragmarx/google2fa-laravel": "^1.3",
|
||||
"rollbar/rollbar-laravel": "^7.0",
|
||||
"spatie/laravel-backup": "^6.16",
|
||||
"symfony/polyfill-mbstring": "^1.22",
|
||||
"tecnickcom/tc-lib-barcode": "^1.15",
|
||||
"unicodeveloper/laravel-password": "^1.0",
|
||||
"watson/validating": "^6.1"
|
||||
|
|
142
composer.lock
generated
142
composer.lock
generated
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "9bd2bbbd4b08d23336364da3d3a4561a",
|
||||
"content-hash": "590171872e4a6a29c78efde99fbbf00e",
|
||||
"packages": [
|
||||
{
|
||||
"name": "alek13/slack",
|
||||
|
@ -1810,24 +1810,24 @@
|
|||
},
|
||||
{
|
||||
"name": "dompdf/dompdf",
|
||||
"version": "v2.0.0",
|
||||
"version": "v2.0.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/dompdf/dompdf.git",
|
||||
"reference": "79573d8b8a141ec8a17312515de8740eed014fa9"
|
||||
"reference": "e8d2d5e37e8b0b30f0732a011295ab80680d7e85"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/dompdf/dompdf/zipball/79573d8b8a141ec8a17312515de8740eed014fa9",
|
||||
"reference": "79573d8b8a141ec8a17312515de8740eed014fa9",
|
||||
"url": "https://api.github.com/repos/dompdf/dompdf/zipball/e8d2d5e37e8b0b30f0732a011295ab80680d7e85",
|
||||
"reference": "e8d2d5e37e8b0b30f0732a011295ab80680d7e85",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-dom": "*",
|
||||
"ext-mbstring": "*",
|
||||
"masterminds/html5": "^2.0",
|
||||
"phenx/php-font-lib": "^0.5.4",
|
||||
"phenx/php-svg-lib": "^0.3.3 || ^0.4.0",
|
||||
"phenx/php-font-lib": ">=0.5.4 <1.0.0",
|
||||
"phenx/php-svg-lib": ">=0.3.3 <1.0.0",
|
||||
"php": "^7.1 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
|
@ -1858,25 +1858,17 @@
|
|||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Ménager",
|
||||
"email": "fabien.menager@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Brian Sweeney",
|
||||
"email": "eclecticgeek@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Gabriel Bull",
|
||||
"email": "me@gabrielbull.com"
|
||||
"name": "The Dompdf Community",
|
||||
"homepage": "https://github.com/dompdf/dompdf/blob/master/AUTHORS.md"
|
||||
}
|
||||
],
|
||||
"description": "DOMPDF is a CSS 2.1 compliant HTML to PDF converter",
|
||||
"homepage": "https://github.com/dompdf/dompdf",
|
||||
"support": {
|
||||
"issues": "https://github.com/dompdf/dompdf/issues",
|
||||
"source": "https://github.com/dompdf/dompdf/tree/v2.0.0"
|
||||
"source": "https://github.com/dompdf/dompdf/tree/v2.0.3"
|
||||
},
|
||||
"time": "2022-06-21T21:14:57+00:00"
|
||||
"time": "2023-02-07T12:51:48+00:00"
|
||||
},
|
||||
{
|
||||
"name": "dragonmantank/cron-expression",
|
||||
|
@ -5131,16 +5123,16 @@
|
|||
},
|
||||
{
|
||||
"name": "masterminds/html5",
|
||||
"version": "2.7.5",
|
||||
"version": "2.7.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Masterminds/html5-php.git",
|
||||
"reference": "f640ac1bdddff06ea333a920c95bbad8872429ab"
|
||||
"reference": "897eb517a343a2281f11bc5556d6548db7d93947"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Masterminds/html5-php/zipball/f640ac1bdddff06ea333a920c95bbad8872429ab",
|
||||
"reference": "f640ac1bdddff06ea333a920c95bbad8872429ab",
|
||||
"url": "https://api.github.com/repos/Masterminds/html5-php/zipball/897eb517a343a2281f11bc5556d6548db7d93947",
|
||||
"reference": "897eb517a343a2281f11bc5556d6548db7d93947",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -5194,9 +5186,9 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/Masterminds/html5-php/issues",
|
||||
"source": "https://github.com/Masterminds/html5-php/tree/2.7.5"
|
||||
"source": "https://github.com/Masterminds/html5-php/tree/2.7.6"
|
||||
},
|
||||
"time": "2021-07-01T14:25:37+00:00"
|
||||
"time": "2022-08-18T16:18:26+00:00"
|
||||
},
|
||||
{
|
||||
"name": "maximebf/debugbar",
|
||||
|
@ -6299,6 +6291,92 @@
|
|||
},
|
||||
"time": "2020-10-15T08:29:30+00:00"
|
||||
},
|
||||
{
|
||||
"name": "paragonie/sodium_compat",
|
||||
"version": "v1.19.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/paragonie/sodium_compat.git",
|
||||
"reference": "cb15e403ecbe6a6cc515f855c310eb6b1872a933"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/paragonie/sodium_compat/zipball/cb15e403ecbe6a6cc515f855c310eb6b1872a933",
|
||||
"reference": "cb15e403ecbe6a6cc515f855c310eb6b1872a933",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"paragonie/random_compat": ">=1",
|
||||
"php": "^5.2.4|^5.3|^5.4|^5.5|^5.6|^7|^8"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^3|^4|^5|^6|^7|^8|^9"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-libsodium": "PHP < 7.0: Better performance, password hashing (Argon2i), secure memory management (memzero), and better security.",
|
||||
"ext-sodium": "PHP >= 7.0: Better performance, password hashing (Argon2i), secure memory management (memzero), and better security."
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"autoload.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"ISC"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Paragon Initiative Enterprises",
|
||||
"email": "security@paragonie.com"
|
||||
},
|
||||
{
|
||||
"name": "Frank Denis",
|
||||
"email": "jedisct1@pureftpd.org"
|
||||
}
|
||||
],
|
||||
"description": "Pure PHP implementation of libsodium; uses the PHP extension if it exists",
|
||||
"keywords": [
|
||||
"Authentication",
|
||||
"BLAKE2b",
|
||||
"ChaCha20",
|
||||
"ChaCha20-Poly1305",
|
||||
"Chapoly",
|
||||
"Curve25519",
|
||||
"Ed25519",
|
||||
"EdDSA",
|
||||
"Edwards-curve Digital Signature Algorithm",
|
||||
"Elliptic Curve Diffie-Hellman",
|
||||
"Poly1305",
|
||||
"Pure-PHP cryptography",
|
||||
"RFC 7748",
|
||||
"RFC 8032",
|
||||
"Salpoly",
|
||||
"Salsa20",
|
||||
"X25519",
|
||||
"XChaCha20-Poly1305",
|
||||
"XSalsa20-Poly1305",
|
||||
"Xchacha20",
|
||||
"Xsalsa20",
|
||||
"aead",
|
||||
"cryptography",
|
||||
"ecdh",
|
||||
"elliptic curve",
|
||||
"elliptic curve cryptography",
|
||||
"encryption",
|
||||
"libsodium",
|
||||
"php",
|
||||
"public-key cryptography",
|
||||
"secret-key cryptography",
|
||||
"side-channel resistant"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/paragonie/sodium_compat/issues",
|
||||
"source": "https://github.com/paragonie/sodium_compat/tree/v1.19.0"
|
||||
},
|
||||
"time": "2022-09-26T03:40:35+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phenx/php-font-lib",
|
||||
"version": "0.5.4",
|
||||
|
@ -6345,21 +6423,21 @@
|
|||
},
|
||||
{
|
||||
"name": "phenx/php-svg-lib",
|
||||
"version": "0.4.1",
|
||||
"version": "0.5.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/dompdf/php-svg-lib.git",
|
||||
"reference": "4498b5df7b08e8469f0f8279651ea5de9626ed02"
|
||||
"reference": "76876c6cf3080bcb6f249d7d59705108166a6685"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/dompdf/php-svg-lib/zipball/4498b5df7b08e8469f0f8279651ea5de9626ed02",
|
||||
"reference": "4498b5df7b08e8469f0f8279651ea5de9626ed02",
|
||||
"url": "https://api.github.com/repos/dompdf/php-svg-lib/zipball/76876c6cf3080bcb6f249d7d59705108166a6685",
|
||||
"reference": "76876c6cf3080bcb6f249d7d59705108166a6685",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-mbstring": "*",
|
||||
"php": "^7.1 || ^7.2 || ^7.3 || ^7.4 || ^8.0",
|
||||
"php": "^7.1 || ^8.0",
|
||||
"sabberworm/php-css-parser": "^8.4"
|
||||
},
|
||||
"require-dev": {
|
||||
|
@ -6385,9 +6463,9 @@
|
|||
"homepage": "https://github.com/PhenX/php-svg-lib",
|
||||
"support": {
|
||||
"issues": "https://github.com/dompdf/php-svg-lib/issues",
|
||||
"source": "https://github.com/dompdf/php-svg-lib/tree/0.4.1"
|
||||
"source": "https://github.com/dompdf/php-svg-lib/tree/0.5.0"
|
||||
},
|
||||
"time": "2022-03-07T12:52:04+00:00"
|
||||
"time": "2022-09-06T12:16:56+00:00"
|
||||
},
|
||||
{
|
||||
"name": "php-http/message-factory",
|
||||
|
|
|
@ -117,6 +117,11 @@ $config = [
|
|||
\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;
|
||||
},
|
||||
],
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
<?php
|
||||
return array (
|
||||
'app_version' => 'v6.0.14',
|
||||
'full_app_version' => 'v6.0.14 - build 9161-g799c9c910',
|
||||
'build_version' => '9161',
|
||||
'full_app_version' => 'v6.0.14 - build 9715-g8b70a7f21',
|
||||
'build_version' => '9715',
|
||||
'prerelease_version' => '',
|
||||
'hash_version' => 'g799c9c910',
|
||||
'full_hash' => 'v6.0.14-117-g799c9c910',
|
||||
'branch' => 'master',
|
||||
'hash_version' => 'g8b70a7f21',
|
||||
'full_hash' => 'v6.0.14-671-g8b70a7f21',
|
||||
'branch' => 'develop',
|
||||
);
|
|
@ -55,7 +55,7 @@ class ActionlogFactory extends Factory
|
|||
[
|
||||
'assigned_to' => $target->id,
|
||||
'assigned_type' => \App\Models\User::class,
|
||||
'assigned_to' => $target->location_id,
|
||||
'location_id' => $target->location_id,
|
||||
]
|
||||
);
|
||||
|
||||
|
@ -84,7 +84,7 @@ class ActionlogFactory extends Factory
|
|||
[
|
||||
'assigned_to' => $target->id,
|
||||
'assigned_type' => \App\Models\Location::class,
|
||||
'assigned_to' => $target->id,
|
||||
'location_id' => $target->id,
|
||||
]
|
||||
);
|
||||
|
||||
|
|
|
@ -38,16 +38,16 @@ class AssetFactory extends Factory
|
|||
{
|
||||
return [
|
||||
'name' => null,
|
||||
'rtd_location_id' => Location::all()->random()->id,
|
||||
'serial' => $this->faker->uuid,
|
||||
'rtd_location_id' => Location::factory(),
|
||||
'serial' => $this->faker->uuid(),
|
||||
'status_id' => 1,
|
||||
'user_id' => 1,
|
||||
'asset_tag' => $this->faker->unixTime('now'),
|
||||
'notes' => 'Created by DB seeder',
|
||||
'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, '299.99', '2999.99'),
|
||||
'order_number' => $this->faker->numberBetween(1000000, 50000000),
|
||||
'supplier_id' => Supplier::all()->random()->id,
|
||||
'supplier_id' => Supplier::factory(),
|
||||
'requestable' => $this->faker->boolean(),
|
||||
'assigned_to' => null,
|
||||
'assigned_type' => null,
|
||||
|
|
|
@ -46,7 +46,7 @@ class LicenseFactory extends Factory
|
|||
'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()),
|
||||
'purchase_date' => $this->faker->dateTimeBetween('-1 years', 'now', date_default_timezone_get())->format('Y-m-d'),
|
||||
'order_number' => $this->faker->numberBetween(1000000, 50000000),
|
||||
'expiration_date' => $this->faker->dateTimeBetween('now', '+3 years', date_default_timezone_get())->format('Y-m-d H:i:s'),
|
||||
'reassignable' => $this->faker->boolean(),
|
||||
|
|
|
@ -52,4 +52,13 @@ class SettingFactory extends Factory
|
|||
'email_domain' => 'test.com',
|
||||
];
|
||||
}
|
||||
|
||||
public function withMultipleFullCompanySupport()
|
||||
{
|
||||
return $this->state(function () {
|
||||
return [
|
||||
'full_multiple_companies_support' => 1,
|
||||
];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,18 +39,18 @@ class SupplierFactory extends Factory
|
|||
public function definition()
|
||||
{
|
||||
return [
|
||||
'name' => $this->faker->company,
|
||||
'address' => $this->faker->streetAddress,
|
||||
'address2' => $this->faker->secondaryAddress,
|
||||
'city' => $this->faker->city,
|
||||
'state' => $this->faker->stateAbbr,
|
||||
'zip' => $this->faker->postCode,
|
||||
'country' => $this->faker->countryCode,
|
||||
'contact' => $this->faker->name,
|
||||
'phone' => $this->faker->phoneNumber,
|
||||
'fax' => $this->faker->phoneNumber,
|
||||
'email' => $this->faker->safeEmail,
|
||||
'url' => $this->faker->url,
|
||||
'name' => $this->faker->company(),
|
||||
'address' => $this->faker->streetAddress(),
|
||||
'address2' => $this->faker->secondaryAddress(),
|
||||
'city' => $this->faker->city(),
|
||||
'state' => $this->faker->stateAbbr(),
|
||||
'zip' => $this->faker->postCode(),
|
||||
'country' => $this->faker->countryCode(),
|
||||
'contact' => $this->faker->name(),
|
||||
'phone' => $this->faker->phoneNumber(),
|
||||
'fax' => $this->faker->phoneNumber(),
|
||||
'email' => $this->faker->safeEmail(),
|
||||
'url' => $this->faker->url(),
|
||||
'notes' => $this->faker->text(191), // Supplier notes can be a max of 255 characters.
|
||||
];
|
||||
}
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class AddsShouldAutoassignBoolToUsersTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table) {
|
||||
$table->boolean('autoassign_licenses')->nullable(false)->default(1);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table) {
|
||||
$table->dropColumn('autoassign_licenses');
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use App\Models\Asset;
|
||||
use App\Models\AssetModel;
|
||||
|
||||
class AddEolDateOnAssetsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
|
||||
Schema::table('assets', function (Blueprint $table) {
|
||||
if (!Schema::hasColumn('assets', 'asset_eol_date')) {
|
||||
$table->date('asset_eol_date')->after('purchase_date')->nullable()->default(null);
|
||||
}
|
||||
});
|
||||
|
||||
// Chunk the model query to get the models that do have an EOL date
|
||||
AssetModel::whereNotNull('eol')->with('assets')->chunk(200, function ($models) {
|
||||
foreach ($models as $model) {
|
||||
foreach ($model->assets as $asset) {
|
||||
|
||||
if ($asset->purchase_date!='') {
|
||||
$asset->asset_eol_date = $asset->present()->eol_date();
|
||||
$asset->save();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('assets', function (Blueprint $table) {
|
||||
if (Schema::hasColumn('assets', 'asset_eol_date')) {
|
||||
$table->dropColumn('asset_eol_date');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
34
database/migrations/2023_01_23_232933_add_vip_to_users.php
Normal file
34
database/migrations/2023_01_23_232933_add_vip_to_users.php
Normal file
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class AddVipToUsers extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table) {
|
||||
$table->boolean('vip')->nullable()->default(0);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table) {
|
||||
if (Schema::hasColumn('users', 'vip')) {
|
||||
$table->dropColumn('vip');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
12
package-lock.json
generated
12
package-lock.json
generated
|
@ -1329,9 +1329,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"@fortawesome/fontawesome-free": {
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-6.2.1.tgz",
|
||||
"integrity": "sha512-viouXhegu/TjkvYQoiRZK3aax69dGXxgEjpvZW81wIJdxm5Fnvp3VVIP4VHKqX4SvFw6qpmkILkD4RJWAdrt7A=="
|
||||
"version": "6.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-6.3.0.tgz",
|
||||
"integrity": "sha512-qVtd5i1Cc7cdrqnTWqTObKQHjPWAiRwjUPaXObaeNPcy7+WKxJumGBx66rfSFgK6LNpIasVKkEgW8oyf0tmPLA=="
|
||||
},
|
||||
"@jridgewell/gen-mapping": {
|
||||
"version": "0.1.1",
|
||||
|
@ -2033,9 +2033,9 @@
|
|||
}
|
||||
},
|
||||
"acorn": {
|
||||
"version": "8.8.0",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz",
|
||||
"integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w=="
|
||||
"version": "8.8.2",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz",
|
||||
"integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw=="
|
||||
},
|
||||
"acorn-import-assertions": {
|
||||
"version": "1.8.0",
|
||||
|
|
|
@ -24,8 +24,8 @@
|
|||
"vue-template-compiler": "2.4.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-free": "^6.2.1",
|
||||
"acorn": "^8.8.0",
|
||||
"@fortawesome/fontawesome-free": "^6.3.0",
|
||||
"acorn": "^8.8.2",
|
||||
"acorn-import-assertions": "^1.8.0",
|
||||
"admin-lte": "^2.4.18",
|
||||
"ajv": "^6.12.6",
|
||||
|
|
28
phpunit.xml
28
phpunit.xml
|
@ -1,22 +1,36 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" backupGlobals="false" backupStaticAttributes="false" bootstrap="bootstrap/autoload.php" colors="true" convertErrorsToExceptions="true" convertNoticesToExceptions="true" convertWarningsToExceptions="true" processIsolation="false" stopOnFailure="false" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd">
|
||||
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
backupGlobals="false"
|
||||
backupStaticAttributes="false"
|
||||
bootstrap="bootstrap/autoload.php"
|
||||
colors="true"
|
||||
convertErrorsToExceptions="true"
|
||||
convertNoticesToExceptions="true"
|
||||
convertWarningsToExceptions="true"
|
||||
processIsolation="false"
|
||||
stopOnFailure="false"
|
||||
xsi:noNamespaceSchemaLocation="./vendor/phpunit/phpunit/phpunit.xsd"
|
||||
>
|
||||
<coverage>
|
||||
<include>
|
||||
<directory suffix=".php">app/</directory>
|
||||
</include>
|
||||
</coverage>
|
||||
<testsuites>
|
||||
<testsuite name="Application Test Suite">
|
||||
<directory>./tests/</directory>
|
||||
<testsuite name="Unit">
|
||||
<directory suffix="Test.php">./tests/Unit</directory>
|
||||
</testsuite>
|
||||
<testsuite name="Feature">
|
||||
<directory suffix="Test.php">./tests/Feature</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
<php>
|
||||
<env name="APP_ENV" value="testing-ci"/>
|
||||
<env name="APP_ENV" value="testing"/>
|
||||
<env name="BCRYPT_ROUNDS" value="4"/>
|
||||
<env name="CACHE_DRIVER" value="array"/>
|
||||
<env name="SESSION_DRIVER" value="array"/>
|
||||
<env name="MAIL_DRIVER" value="array"/>
|
||||
<env name="QUEUE_DRIVER" value="sync"/>
|
||||
<env name="DB_CONNECTION" value="sqlite"/>
|
||||
<server name="SERVER_NAME" value="http://127.0.0.1:8000"/>
|
||||
<env name="SESSION_DRIVER" value="array"/>
|
||||
<ini name="display_errors" value="true"/>
|
||||
</php>
|
||||
</phpunit>
|
||||
|
|
Binary file not shown.
Binary file not shown.
BIN
public/css/dist/all.css
vendored
BIN
public/css/dist/all.css
vendored
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
public/js/dist/all.js
vendored
BIN
public/js/dist/all.js
vendored
Binary file not shown.
|
@ -1,8 +1,8 @@
|
|||
{
|
||||
"/js/build/app.js": "/js/build/app.js?id=f05cc05b9000ba73e1949bcf137d4301",
|
||||
"/js/build/app.js": "/js/build/app.js?id=da037f537476ebca094531163cb611f5",
|
||||
"/css/dist/skins/skin-blue.css": "/css/dist/skins/skin-blue.css?id=f677207c6cf9678eb539abecb408c374",
|
||||
"/css/build/overrides.css": "/css/build/overrides.css?id=0465141b9ecb0662ba6790c1460f391f",
|
||||
"/css/build/app.css": "/css/build/app.css?id=c3a896cab26e2093f8be24336b7db1b9",
|
||||
"/css/build/overrides.css": "/css/build/overrides.css?id=d9175e3d9b9074397343dddebfe23888",
|
||||
"/css/build/app.css": "/css/build/app.css?id=dcb8aa9f4501a370214a67442e88daf0",
|
||||
"/css/build/AdminLTE.css": "/css/build/AdminLTE.css?id=dc383f8560a8d4adb51d44fb4043e03b",
|
||||
"/css/dist/skins/skin-orange.css": "/css/dist/skins/skin-orange.css?id=6f0563e726c2fe4fab4026daaa5bfdf2",
|
||||
"/css/dist/skins/skin-orange-dark.css": "/css/dist/skins/skin-orange-dark.css?id=f343f659ca1d45534d2c2c3cc30fb619",
|
||||
|
@ -18,23 +18,23 @@
|
|||
"/css/dist/skins/skin-green.css": "/css/dist/skins/skin-green.css?id=0a82a6ae6bb4e58fe62d162c4fb50397",
|
||||
"/css/dist/skins/skin-contrast.css": "/css/dist/skins/skin-contrast.css?id=da6c7997d9de2f8329142399f0ce50da",
|
||||
"/css/dist/skins/skin-red.css": "/css/dist/skins/skin-red.css?id=44bf834f2110504a793dadec132a5898",
|
||||
"/css/dist/all.css": "/css/dist/all.css?id=ef030b613d45620b907cf0184a14e868",
|
||||
"/css/dist/all.css": "/css/dist/all.css?id=0314c741a636de602ec952468eb171f3",
|
||||
"/css/blue.png": "/css/blue.png?id=e83a6c29e04fe851f2122815b2e4b150",
|
||||
"/css/blue@2x.png": "/css/blue@2x.png?id=51135dd4d24f88f5de0b2414bd51dac5",
|
||||
"/css/dist/signature-pad.css": "/css/dist/signature-pad.css?id=6a89d3cd901305e66ced1cf5f13147f7",
|
||||
"/css/dist/signature-pad.min.css": "/css/dist/signature-pad.min.css?id=6a89d3cd901305e66ced1cf5f13147f7",
|
||||
"/css/webfonts/fa-brands-400.ttf": "/css/webfonts/fa-brands-400.ttf?id=0b834d6c0ecc5bf275a83414eb38efd4",
|
||||
"/css/webfonts/fa-brands-400.woff2": "/css/webfonts/fa-brands-400.woff2?id=a46924ee2a2a7702ef7fe7ead62fca18",
|
||||
"/css/webfonts/fa-regular-400.ttf": "/css/webfonts/fa-regular-400.ttf?id=93d1ca4fec25c46c9ac67b07058b3f72",
|
||||
"/css/webfonts/fa-regular-400.woff2": "/css/webfonts/fa-regular-400.woff2?id=d8373194363409c201ee33fcd48ba574",
|
||||
"/css/webfonts/fa-solid-900.ttf": "/css/webfonts/fa-solid-900.ttf?id=a7d60e1f645d1b80e0879b2c8e72ed06",
|
||||
"/css/webfonts/fa-solid-900.woff2": "/css/webfonts/fa-solid-900.woff2?id=3e1cccc95e0dadb2168d67c2f0f23bf3",
|
||||
"/css/webfonts/fa-v4compatibility.ttf": "/css/webfonts/fa-v4compatibility.ttf?id=ee335846f3552dc6af2ef7c8cafae1dc",
|
||||
"/css/webfonts/fa-v4compatibility.woff2": "/css/webfonts/fa-v4compatibility.woff2?id=1ad361f755ce9c96dadb8da2d7318975",
|
||||
"/css/webfonts/fa-brands-400.ttf": "/css/webfonts/fa-brands-400.ttf?id=2df05d4beaa48550d71234e8dca79141",
|
||||
"/css/webfonts/fa-brands-400.woff2": "/css/webfonts/fa-brands-400.woff2?id=682885a4f72597322017a9fcd0683831",
|
||||
"/css/webfonts/fa-regular-400.ttf": "/css/webfonts/fa-regular-400.ttf?id=e7a7f9dd9376f68614860d920255d4df",
|
||||
"/css/webfonts/fa-regular-400.woff2": "/css/webfonts/fa-regular-400.woff2?id=204fc700c679395e6aa9bebc3cada64e",
|
||||
"/css/webfonts/fa-solid-900.ttf": "/css/webfonts/fa-solid-900.ttf?id=c9d3294ec75b843a31ef711069a0f0b6",
|
||||
"/css/webfonts/fa-solid-900.woff2": "/css/webfonts/fa-solid-900.woff2?id=6707d0247b0bca1b4964bab435e3c0d6",
|
||||
"/css/webfonts/fa-v4compatibility.ttf": "/css/webfonts/fa-v4compatibility.ttf?id=a947172f4fde88e43b4c1a60b01db061",
|
||||
"/css/webfonts/fa-v4compatibility.woff2": "/css/webfonts/fa-v4compatibility.woff2?id=bbc23038a6067c78310d3f19432a3ebf",
|
||||
"/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=4f9355ac85d380301f6f62e55b1a6e5e",
|
||||
"/js/dist/all.js": "/js/dist/all.js?id=758f256419ccaf4b4266da3bbc742b0b",
|
||||
"/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",
|
||||
|
|
|
@ -161,6 +161,7 @@
|
|||
{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"},
|
||||
|
@ -195,6 +196,7 @@
|
|||
{id: 'country', text: 'Country' },
|
||||
{id: 'zip', text: 'ZIP' },
|
||||
{id: 'remote', text: 'Remote'},
|
||||
{id: 'vip', text: 'VIP'},
|
||||
|
||||
],
|
||||
customFields: this.customFields,
|
||||
|
|
|
@ -540,10 +540,16 @@ $(document).ready(function () {
|
|||
var id = '#' + $this.attr('id');
|
||||
var status = id + '-status';
|
||||
var $status = $(status);
|
||||
var delete_id = $(id + '-deleteCheckbox');
|
||||
var preview_container = $(id + '-previewContainer');
|
||||
|
||||
|
||||
|
||||
$status.removeClass('text-success').removeClass('text-danger');
|
||||
$(status + ' .goodfile').remove();
|
||||
$(status + ' .badfile').remove();
|
||||
$(status + ' .previewSize').hide();
|
||||
preview_container.hide();
|
||||
$(id + '-info').html('');
|
||||
|
||||
var max_size = $this.data('maxsize');
|
||||
|
@ -554,17 +560,15 @@ $(document).ready(function () {
|
|||
$(id + '-info').append('<span class="label label-default">' + htmlEntities(this.files[i].name) + ' (' + formatBytes(this.files[i].size) + ')</span> ');
|
||||
}
|
||||
|
||||
console.log('Max size is: ' + max_size);
|
||||
console.log('Real size is: ' + total_size);
|
||||
|
||||
if (total_size > max_size) {
|
||||
$status.addClass('text-danger').removeClass('help-block').prepend('<i class="badfile fas fa-times"></i> ').append('<span class="previewSize"> Upload is ' + formatBytes(total_size) + '.</span>');
|
||||
} else {
|
||||
|
||||
$status.addClass('text-success').removeClass('help-block').prepend('<i class="goodfile fas fa-check"></i> ');
|
||||
var $preview = $(id + '-imagePreview');
|
||||
readURL(this, $preview);
|
||||
$preview.fadeIn();
|
||||
preview_container.fadeIn();
|
||||
delete_id.hide();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -671,18 +671,18 @@ th.css-accessory > .th-inner::before
|
|||
}
|
||||
@media screen and (max-width: 511px){
|
||||
.sidebar-menu{
|
||||
margin-top:64px;
|
||||
margin-top:160px;
|
||||
}
|
||||
}
|
||||
@media screen and (max-width: 771px) and (min-width: 512px){
|
||||
.sidebar-menu {
|
||||
margin-top:14px
|
||||
margin-top:160px
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1098px) and (min-width: 772px){
|
||||
.sidebar-menu {
|
||||
margin-top:51px
|
||||
margin-top:98px
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -395,7 +395,7 @@ return [
|
|||
'end_date' => 'Enddatum',
|
||||
'alt_uploaded_image_thumbnail' => 'Hochgeladene Miniaturansicht',
|
||||
'placeholder_kit' => 'Kit auswählen',
|
||||
'file_not_found' => 'File not found',
|
||||
'file_not_found' => 'File not found on server',
|
||||
'preview_not_available' => '(no preview)',
|
||||
'setup' => 'Setup',
|
||||
'pre_flight' => 'Pre-Flight',
|
||||
|
|
|
@ -11,7 +11,7 @@ return [
|
|||
'admin_cc_email_help' => 'If you would like to send a copy of checkin/checkout emails that are sent to users to an additional email account, enter it here. Otherwise leave this field blank.',
|
||||
'is_ad' => 'This is an Active Directory server',
|
||||
'alerts' => 'Alerts',
|
||||
'alert_title' => 'Update Alert Settings',
|
||||
'alert_title' => 'Update Notification Settings',
|
||||
'alert_email' => 'Send alerts to',
|
||||
'alert_email_help' => 'Email addresses or distribution lists you want alerts to be sent to, comma separated',
|
||||
'alerts_enabled' => 'Email Alerts Enabled',
|
||||
|
|
|
@ -19,6 +19,8 @@ return [
|
|||
'print_assigned' => 'Print All Assigned',
|
||||
'email_assigned' => 'Email List of All Assigned',
|
||||
'user_notified' => 'User has been emailed a list of their currently assigned items.',
|
||||
'auto_assign_label' => 'Include this user when auto-assigning eligible licenses',
|
||||
'auto_assign_help' => 'Skip this user in auto assignment of licenses',
|
||||
'software_user' => 'Software Checked out to :name',
|
||||
'send_email_help' => 'You must provide an email address for this user to send them credentials. Emailing credentials can only be done on user creation. Passwords are stored in a one-way hash and cannot be retrieved once saved.',
|
||||
'view_user' => 'View User :name',
|
||||
|
@ -41,4 +43,11 @@ return [
|
|||
'remote' => 'Remote',
|
||||
'remote_help' => 'This can be useful if you need to filter by remote users who never or rarely come into your physical locations.',
|
||||
'not_remote_label' => 'This is not a remote user',
|
||||
];
|
||||
'vip_label' => 'VIP user',
|
||||
'vip_help' => 'This can be helpful to mark important people if you would like',
|
||||
'create_user' => 'Create a user',
|
||||
'create_user_page_explanation' => 'This is the account information you will use to access the site for the first time.',
|
||||
'email_credentials' => 'Email credentials',
|
||||
'email_credentials_text' => 'Email my credentials to the email address above',
|
||||
'next_save_user' => 'Next: Save User',
|
||||
];
|
||||
|
|
|
@ -148,6 +148,7 @@ return [
|
|||
'filetypes_accepted_help' => 'Accepted filetype is :types. Max upload size allowed is :size.|Accepted filetypes are :types. Max upload size allowed is :size.',
|
||||
'filetypes_size_help' => 'Max upload size allowed is :size.',
|
||||
'image_filetypes_help' => 'Accepted filetypes are jpg, webp, png, gif, and svg. Max upload size allowed is :size.',
|
||||
'unaccepted_image_type' => 'This image file was not readable. Accepted filetypes are jpg, webp, png, gif, and svg. The mimetype of this file is: :mimetype.',
|
||||
'import' => 'Import',
|
||||
'importing' => 'Importing',
|
||||
'importing_help' => 'You can import assets, accessories, licenses, components, consumables, and users via CSV file. <br><br>The CSV should be comma-delimited and formatted with headers that match the ones in the <a href="https://snipe-it.readme.io/docs/importing" target="_new">sample CSVs in the documentation</a>.',
|
||||
|
@ -403,6 +404,8 @@ return [
|
|||
'toggle_navigation' => 'Toggle navigation',
|
||||
'alerts' => 'Alerts',
|
||||
'tasks_view_all' => 'View all tasks',
|
||||
'true' => 'True',
|
||||
'false' => 'False',
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
<li class="active">
|
||||
<a href="#items" data-toggle="tab" title="{{ trans('general.items') }}"> {{ ucwords($category_type_route) }}
|
||||
@if ($category->category_type=='asset')
|
||||
<badge class="badge badge-secondary"> {{ $category->assets()->AssetsForShow()->count() }}</badge>
|
||||
<badge class="badge badge-secondary"> {{ $category->showableAssets()->count() }}</badge>
|
||||
@endif
|
||||
</a>
|
||||
</li>
|
||||
|
|
|
@ -274,7 +274,7 @@
|
|||
</div> <!--/row-->
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<!-- Categories -->
|
||||
<!-- Locations -->
|
||||
<div class="box box-default">
|
||||
<div class="box-header with-border">
|
||||
<h2 class="box-title">{{ trans('general.asset') }} {{ trans('general.locations') }}</h2>
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-switchable="true" data-sortable="false" data-field="id" data-visible="false">{{ trans('general.id') }}</th>
|
||||
<th data-switchable="true" data-sortable="true" data-field="id" data-visible="false">{{ trans('general.id') }}</th>
|
||||
<th data-switchable="true" data-sortable="true" data-field="name" data-formatter="groupsAdminLinkFormatter" data-visible="true">{{ trans('admin/groups/table.name') }}</th>
|
||||
<th data-switchable="true" data-sortable="true" data-field="users_count" data-visible="true">{{ trans('admin/groups/table.users') }}</th>
|
||||
<th data-switchable="true" data-sortable="true" data-field="created_at" data-visible="true" data-formatter="dateDisplayFormatter">{{ trans('general.created_at') }}</th>
|
||||
|
|
|
@ -26,6 +26,16 @@
|
|||
</div>
|
||||
<div class="box-body">
|
||||
{{csrf_field()}}
|
||||
@if ($asset->company && $asset->company->name)
|
||||
<div class="form-group">
|
||||
{{ Form::label('model', trans('general.company'), array('class' => 'col-md-3 control-label')) }}
|
||||
<div class="col-md-8">
|
||||
<p class="form-control-static">
|
||||
{{ $asset->company->name }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
<!-- AssetModel name -->
|
||||
<div class="form-group">
|
||||
{{ Form::label('model', trans('admin/hardware/form.model'), array('class' => 'col-md-3 control-label')) }}
|
||||
|
@ -33,7 +43,6 @@
|
|||
<p class="form-control-static">
|
||||
@if (($asset->model) && ($asset->model->name))
|
||||
{{ $asset->model->name }}
|
||||
|
||||
@else
|
||||
<span class="text-danger text-bold">
|
||||
<i class="fas fa-exclamation-triangle"></i>{{ trans('admin/hardware/general.model_invalid')}}
|
||||
|
@ -168,4 +177,4 @@
|
|||
|
||||
|
||||
</script>
|
||||
@stop
|
||||
@stop
|
||||
|
|
|
@ -152,6 +152,7 @@
|
|||
<br>
|
||||
@include ('partials.forms.edit.order_number')
|
||||
@include ('partials.forms.edit.purchase_date')
|
||||
@include ('partials.forms.edit.eol_date')
|
||||
@include ('partials.forms.edit.supplier-select', ['translated_name' => trans('general.supplier'), 'fieldname' => 'supplier_id'])
|
||||
|
||||
@php
|
||||
|
|
|
@ -673,7 +673,8 @@
|
|||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@endif
|
||||
@if ($asset->asset_eol_date)
|
||||
<div class="row">
|
||||
<div class="col-md-2">
|
||||
<strong>
|
||||
|
@ -681,10 +682,10 @@
|
|||
</strong>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
@if ($asset->purchase_date)
|
||||
{{ Helper::getFormattedDateObject($asset->present()->eol_date(), 'date', false) }}
|
||||
@if ($asset->asset_eol_date)
|
||||
{{ Helper::getFormattedDateObject($asset->asset_eol_date, 'date', false) }}
|
||||
-
|
||||
{{ Carbon::parse($asset->present()->eol_date())->diffForHumans(['parts' => 2]) }}
|
||||
{{ Carbon::parse($asset->asset_eol_date)->diffForHumans(['parts' => 2]) }}
|
||||
@else
|
||||
{{ trans('general.na_no_purchase_date') }}
|
||||
@endif
|
||||
|
|
|
@ -358,7 +358,7 @@
|
|||
</strong>
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
{{ $license->reassignable ? 'Yes' : 'No' }}
|
||||
{!! $license->reassignable ? '<i class="fas fa-check text-success" aria-hidden="true"></i> '.trans('general.yes') : '<i class="fas fa-times text-danger" aria-hidden="true"></i> '.trans('general.no') !!}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -65,50 +65,3 @@
|
|||
@include ('partials.forms.edit.image-upload')
|
||||
@stop
|
||||
|
||||
@if (!$item->id)
|
||||
@section('moar_scripts')
|
||||
<script nonce="{{ csrf_token() }}">
|
||||
|
||||
var $eventSelect = $(".parent");
|
||||
$eventSelect.on("change", function () { parent_details($eventSelect.val()); });
|
||||
$(function() {
|
||||
var parent_loc = $(".parent option:selected").val();
|
||||
if(parent_loc!=''){
|
||||
parent_details(parent_loc);
|
||||
}
|
||||
});
|
||||
|
||||
function parent_details(id) {
|
||||
|
||||
if (id) {
|
||||
//start ajax request
|
||||
$.ajax({
|
||||
type: 'GET',
|
||||
url: "{{url('/') }}/api/locations/"+id+"/check",
|
||||
//force to handle it as text
|
||||
dataType: "text",
|
||||
success: function(data) {
|
||||
var json = $.parseJSON(data);
|
||||
$("#city").val(json.city);
|
||||
$("#address").val(json.address);
|
||||
$("#address2").val(json.address2);
|
||||
$("#state").val(json.state);
|
||||
$("#zip").val(json.zip);
|
||||
$(".country").select2("val",json.country);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
$("#city").val('');
|
||||
$("#address").val('');
|
||||
$("#address2").val('');
|
||||
$("#state").val('');
|
||||
$("#zip").val('');
|
||||
$(".country").select2("val",'');
|
||||
}
|
||||
|
||||
|
||||
|
||||
};
|
||||
</script>
|
||||
@stop
|
||||
@endif
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
@php
|
||||
$checkin = Helper::getFormattedDateObject($asset->expected_checkin, 'date');
|
||||
@endphp
|
||||
| [{{ $asset->present()->name }}]({{ route('hardware.show', ['hardware' => $asset->id]) }}) | [{{ $asset->assigned->present()->fullName }}]({{ route('users.show', ['user'=>$asset->assigned->id]) }}) | {{ $checkin['formatted'] }}
|
||||
| [{{ $asset->present()->name }}]({{ route('hardware.show', ['hardware' => $asset->id]) }}) | [{{ $asset->assigned->present()->fullName }}]({{ route($asset->targetShowRoute().'.show', [$asset->assigned->id]) }}) | {{ $checkin['formatted'] }}
|
||||
@endforeach
|
||||
@endcomponent
|
||||
|
||||
|
|
|
@ -9,9 +9,18 @@
|
|||
## {{ $assets->count() }} {{ trans('general.assets') }}
|
||||
|
||||
<table width="100%">
|
||||
<tr><th align="left">{{ trans('mail.name') }} </th><th align="left">{{ trans('mail.asset_tag') }}</th><th align="left">{{ trans('admin/hardware/table.serial') }}</th></tr>
|
||||
<tr><th align="left">{{ trans('mail.name') }} </th><th align="left">{{ trans('mail.asset_tag') }}</th><th align="left">{{ trans('admin/hardware/table.serial') }}</th> <th></th> </tr>
|
||||
@foreach($assets as $asset)
|
||||
<tr><td>{{ $asset->present()->name }}</td><td> {{ $asset->asset_tag }} </td><td> {{ $asset->serial }} </td></tr>
|
||||
<tr>
|
||||
<td>{{ $asset->present()->name }}</td>
|
||||
<td> {{ $asset->asset_tag }} </td>
|
||||
<td> {{ $asset->serial }} </td>
|
||||
@if (($snipeSettings->show_images_in_email =='1') && $asset->getImageUrl())
|
||||
<td>
|
||||
<img src="{{ asset($asset->getImageUrl()) }}" alt="Asset" style="max-width: 64px;">
|
||||
</td>
|
||||
@endif
|
||||
</tr>
|
||||
@endforeach
|
||||
</table>
|
||||
@endif
|
||||
|
@ -20,9 +29,16 @@
|
|||
## {{ $accessories->count() }} {{ trans('general.accessories') }}
|
||||
|
||||
<table width="100%">
|
||||
<tr><th align="left">{{ trans('mail.name') }} </th></tr>
|
||||
<tr><th align="left">{{ trans('mail.name') }} </th> <th></th> </tr>
|
||||
@foreach($accessories as $accessory)
|
||||
<tr><td>{{ $accessory->name }}</td></tr>
|
||||
<tr>
|
||||
<td>{{ $accessory->name }}</td>
|
||||
@if (($snipeSettings->show_images_in_email =='1') && $accessory->getImageUrl())
|
||||
<td>
|
||||
<img src="{{ asset($accessory->getImageUrl()) }}" alt="Accessory" style="max-width: 64px;">
|
||||
</td>
|
||||
@endif
|
||||
</tr>
|
||||
@endforeach
|
||||
</table>
|
||||
@endif
|
||||
|
@ -31,9 +47,11 @@
|
|||
## {{ $licenses->count() }} {{ trans('general.licenses') }}
|
||||
|
||||
<table width="100%">
|
||||
<tr><th align="left"{{ trans('mail.name') }} </th></tr>
|
||||
<tr><th align="left">{{ trans('mail.name') }} </th></tr>
|
||||
@foreach($licenses as $license)
|
||||
<tr><td>{{ $license->name }}</td></tr>
|
||||
<tr>
|
||||
<td>{{ $license->name }}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</table>
|
||||
@endif
|
||||
|
|
|
@ -570,9 +570,9 @@
|
|||
|
||||
function trueFalseFormatter(value) {
|
||||
if ((value) && ((value == 'true') || (value == '1'))) {
|
||||
return '<i class="fas fa-check text-success"></i>';
|
||||
return '<i class="fas fa-check text-success"></i><span class="sr-only">{{ trans('general.true') }}</span>';
|
||||
} else {
|
||||
return '<i class="fas fa-times text-danger"></i>';
|
||||
return '<i class="fas fa-times text-danger"></i><span class="sr-only">{{ trans('general.false') }}</span>';
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
{{ Form::label($fieldname, $translated_name, array('class' => 'col-md-3 control-label')) }}
|
||||
<div class="input-group col-md-4">
|
||||
<div class="input-group date" data-provide="datepicker" data-date-clear-btn="true" data-date-format="yyyy-mm-dd" data-autoclose="true">
|
||||
<input type="text" class="form-control" placeholder="{{ trans('general.select_date') }}" name="{{ $fieldname }}" id="{{ $fieldname }}" value="{{ old($fieldname, ($item->{$fieldname}) ? $item->{$fieldname}->format('Y-m-d') : '') }}" readonly style="background-color:inherit">
|
||||
<input type="text" class="form-control" placeholder="{{ trans('general.select_date') }}" name="{{ $fieldname }}" id="{{ $fieldname }}" value="{{ old($fieldname, ($item->{$fieldname}) ? date('Y-m-d', strtotime($item->{$fieldname})) : '') }}" readonly style="background-color:inherit">
|
||||
<span class="input-group-addon"><i class="fas fa-calendar" aria-hidden="true"></i></span>
|
||||
</div>
|
||||
{!! $errors->first($fieldname, '<span class="alert-msg" aria-hidden="true"><i class="fas fa-times" aria-hidden="true"></i> :message</span>') !!}
|
||||
|
|
11
resources/views/partials/forms/edit/eol_date.blade.php
Normal file
11
resources/views/partials/forms/edit/eol_date.blade.php
Normal file
|
@ -0,0 +1,11 @@
|
|||
<!-- Purchase Date -->
|
||||
<div class="form-group {{ $errors->has('asset_eol_date') ? ' has-error' : '' }}">
|
||||
<label for="asset_eol_date" class="col-md-3 control-label">{{ trans('admin/hardware/form.eol_date') }}</label>
|
||||
<div class="input-group col-md-4">
|
||||
<div class="input-group date" data-provide="datepicker" data-date-clear-btn="true" data-date-format="yyyy-mm-dd" data-autoclose="true">
|
||||
<input type="text" class="form-control" placeholder="{{ trans('general.select_date') }}" name="asset_eol_date" id="asset_eol_date" readonly value="{{ old('asset_eol_date', $item->asset_eol_date ?? $item->present()->eol_date() ?? '') }}" style="background-color:inherit">
|
||||
<span class="input-group-addon"><i class="fas fa-calendar" aria-hidden="true"></i></span>
|
||||
</div>
|
||||
{!! $errors->first('asset_eol_date', '<span class="alert-msg" aria-hidden="true"><i class="fas fa-times" aria-hidden="true"></i> :message</span>') !!}
|
||||
</div>
|
||||
</div>
|
|
@ -1,57 +1,66 @@
|
|||
<div class="form-group {{ $errors->has($logoVariable) ? 'has-error' : '' }}">
|
||||
<!-- {{ $logoVariable }}logo image upload -->
|
||||
|
||||
<div class="form-group">
|
||||
<div class="col-md-3">
|
||||
<strong>{{ $logoLabel }}</strong>
|
||||
<label {!! $errors->has($logoVariable) ? 'class="alert-msg"' : '' !!} for="{{ $logoVariable }}">
|
||||
{{ ucwords(str_replace('_', ' ', $logoVariable)) }}
|
||||
</label>
|
||||
</div>
|
||||
|
||||
@if (($setting->$logoVariable!='') && (Storage::disk('public')->exists(e($snipeSettings->$logoVariable))))
|
||||
<div class="col-md-9">
|
||||
|
||||
<label for="{{ $logoClearVariable }}" style="font-weight: normal">
|
||||
{{ Form::checkbox($logoClearVariable, '1', Request::old($logoClearVariable),array('class' => 'minimal')) }}
|
||||
Remove current {{ str_replace('_', ' ', $logoVariable) }} image
|
||||
|
||||
</label>
|
||||
|
||||
|
||||
<br>
|
||||
@if ($logoVariable!='favicon')
|
||||
<a href="{{ Storage::disk('public')->url(e($snipeSettings->$logoVariable)) }}" data-toggle="lightbox">
|
||||
<img style="max-height: 60px; padding-top: 10px; padding-bottom: 10px; " alt="" src="{{ Storage::disk('public')->url(e($snipeSettings->$logoVariable)) }}">
|
||||
</a>
|
||||
@else
|
||||
<img style="max-height: 50px; padding-top: 10px; padding-bottom: 10px; " alt="" src="{{ Storage::disk('public')->url(e($snipeSettings->$logoVariable)) }}">
|
||||
@endif
|
||||
|
||||
</div>
|
||||
<div class="col-md-9 col-md-offset-3">
|
||||
@else
|
||||
<div class="col-md-9">
|
||||
@endif
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="col-md-9">
|
||||
<label class="btn btn-default">
|
||||
{{ trans('button.select_file') }}
|
||||
<input type="file" name="{{ $logoVariable }}" class="js-uploadFile" id="{{ $logoId }}"
|
||||
data-maxsize="{{ $maxSize ?? Helper::file_upload_max_size() }}"
|
||||
accept="{{ $allowedTypes ?? 'image/gif,image/jpeg,image/png,image/svg,image/svg+xml'}}" style="display:none; max-width: 90%">
|
||||
<input type="file" name="{{ $logoVariable }}" class="js-uploadFile" id="{{ $logoId }}" accept="image/gif,image/jpeg,image/webp,image/png,image/svg,image/svg+xml" data-maxsize="{{ $maxSize ?? Helper::file_upload_max_size() }}"
|
||||
style="display:none; max-width: 90%">
|
||||
</label>
|
||||
|
||||
<span class='label label-default' id="{{ $logoId }}-info"></span>
|
||||
|
||||
<p class="help-block" id="{{ $logoId }}-status">
|
||||
{!! $errors->first($logoVariable, '<span class="alert-msg">:message</span>') !!}
|
||||
|
||||
|
||||
<p class="help-block" style="!important" id="{{ $logoId }}-status">
|
||||
{{ $helpBlock }}
|
||||
</p>
|
||||
|
||||
@if (config('app.lock_passwords')===true)
|
||||
<p class="text-warning"><i class="fas fa-lock"></i> {{ trans('general.feature_disabled') }}</p>
|
||||
@endif
|
||||
{!! $errors->first($logoVariable, '<span class="alert-msg">:message</span>') !!}
|
||||
</div>
|
||||
|
||||
<div class="col-md-9 col-md-offset-3">
|
||||
|
||||
@if (($setting->$logoVariable!='') && (Storage::disk('public')->exists(e($snipeSettings->$logoVariable))))
|
||||
<div class="pull-left" style="padding-right: 20px;">
|
||||
<a href="{{ Storage::disk('public')->url(e($snipeSettings->$logoVariable)) }}"{!! ($logoVariable!='favicon') ? ' data-toggle="lightbox"' : '' !!}>
|
||||
<img id="{{ $logoId }}-imagePreview" style="height: 80px; padding-bottom: 5px;" alt="" src="{{ Storage::disk('public')->url(e($snipeSettings->$logoVariable)) }}">
|
||||
</a>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div id="{{ $logoId }}-previewContainer" style="display: none;">
|
||||
<img id="{{ $logoId }}-imagePreview" style="height: 80px;">
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
@if (($setting->$logoVariable!='') && (Storage::disk('public')->exists(e($snipeSettings->$logoVariable))))
|
||||
|
||||
<div class="col-md-9 col-md-offset-3">
|
||||
<img id="{{ $logoId }}-imagePreview" style="max-width: 500px; max-height: 50px;">
|
||||
<label id="{{ $logoId }}-deleteCheckbox" for="{{ $logoClearVariable }}" style="font-weight: normal">
|
||||
{{ Form::checkbox($logoClearVariable, '1', Request::old($logoClearVariable),array('class' => 'minimal')) }}
|
||||
Remove current {{ ucwords(str_replace('_', ' ', $logoVariable)) }} image
|
||||
</label>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
data-sort-order="asc"
|
||||
id="accessoriesReport"
|
||||
class="table table-striped snipe-table"
|
||||
data-url="{{ route('api.accessories.index') }}"
|
||||
data-export-options='{
|
||||
"fileName": "accessory-report-{{ date('Y-m-d') }}",
|
||||
"ignoreColumn": ["actions","image","change","checkbox","checkincheckout","icon"]
|
||||
|
@ -34,27 +35,17 @@
|
|||
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="col-sm-1">{{ trans('admin/companies/table.title') }}</th>
|
||||
<th class="col-sm-1">{{ trans('admin/accessories/table.title') }}</th>
|
||||
<th class="col-sm-1">{{ trans('general.model_no') }}</th>
|
||||
<th class="col-sm-1">{{ trans('admin/accessories/general.total') }}</th>
|
||||
<th class="col-sm-1">{{ trans('admin/accessories/general.remaining') }}</th>
|
||||
<th class="col-sm-1" data-field="company.name">{{ trans('admin/companies/table.title') }}</th>
|
||||
<th class="col-sm-1" data-field="name">{{ trans('admin/accessories/table.title') }}</th>
|
||||
<th class="col-sm-1" data-field="model_number">{{ trans('general.model_no') }}</th>
|
||||
<th class="col-sm-1" data-field="qty">{{ trans('admin/accessories/general.total') }}</th>
|
||||
<th class="col-sm-1" data-field="remaining_qty">{{ trans('admin/accessories/general.remaining') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach ($accessories as $accessory)
|
||||
<tr>
|
||||
<td>{{ is_null($accessory->company) ? '' : $accessory->company->name }}</td>
|
||||
<td>{{ $accessory->name }}</td>
|
||||
<td>{{ $accessory->model_number }}</td>
|
||||
<td>{{ $accessory->qty }}</td>
|
||||
<td>{{ $accessory->numRemaining() }}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
@extends('layouts/setup')
|
||||
{{-- TODO: Translate --}}
|
||||
{{-- Page title --}}
|
||||
{{ trans('admin/user/table.createuser') }}
|
||||
@section('title')
|
||||
Create a User ::
|
||||
{{ trans('admin/user/general.create_user') }} ::
|
||||
@parent
|
||||
@stop
|
||||
|
||||
{{-- Page content --}}
|
||||
@section('content')
|
||||
|
||||
<p> This is the account information you'll use to access the site for the first time. </p>
|
||||
<p>{{ trans('admin/user/general.create_user_page_explanation') }}</p>
|
||||
|
||||
<form action="{{ route('setup.user.save') }}" method="POST">
|
||||
{{ csrf_field() }}
|
||||
|
@ -157,10 +156,10 @@ Create a User ::
|
|||
|
||||
<!-- Email credentials -->
|
||||
<div class="form-group col-lg-12">
|
||||
<label>Email credentials</label>
|
||||
<label>{{ trans('admin/user/general.email_credentials') }}</label>
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input type="checkbox" value="1" name="email_creds">Email my credentials to the email address above
|
||||
<input type="checkbox" value="1" name="email_creds">{{ trans('admin/user/general.email_credentials_text') }}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -168,7 +167,7 @@ Create a User ::
|
|||
@stop
|
||||
|
||||
@section('button')
|
||||
<button class="btn btn-primary">Next: Save User</button>
|
||||
<button class="btn btn-primary">{{ trans('admin/user/general.next_save_user') }}</button>
|
||||
</form>
|
||||
@parent
|
||||
@stop
|
||||
|
|
|
@ -370,6 +370,19 @@
|
|||
|
||||
@include ('partials.forms.edit.datepicker', ['translated_name' => trans('general.end_date'), 'fieldname' => 'end_date', 'item' => $user])
|
||||
|
||||
<!-- VIP checkbox -->
|
||||
<div class="form-group">
|
||||
<div class="col-md-7 col-md-offset-3">
|
||||
<label for="vip">
|
||||
<input type="checkbox" value="1" name="vip" class="minimal" {{ (old('vip', $user->vip)) == '1' ? ' checked="checked"' : '' }} aria-label="vip">
|
||||
{{ trans('admin/users/general.vip_label') }}
|
||||
|
||||
</label>
|
||||
<p class="help-block">{{ trans('admin/users/general.vip_help') }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- remote checkbox -->
|
||||
<div class="form-group">
|
||||
|
@ -384,6 +397,19 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Auto Assign checkbox -->
|
||||
<div class="form-group">
|
||||
<div class="col-md-7 col-md-offset-3">
|
||||
<label for="autoassign_licenses">
|
||||
<input type="checkbox" value="1" name="autoassign_licenses" class="minimal" {{ (old('autoassign_licenses', $user->autoassign_licenses)) == '1' ? ' checked="checked"' : '' }} aria-label="autoassign_licenses">
|
||||
{{ trans('admin/users/general.auto_assign_label') }}
|
||||
|
||||
</label>
|
||||
<p class="help-block">{{ trans('admin/users/general.auto_assign_help') }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Location -->
|
||||
@include ('partials.forms.edit.location-select', ['translated_name' => trans('general.location'), 'fieldname' => 'location_id'])
|
||||
|
||||
|
|
|
@ -519,7 +519,17 @@
|
|||
</div>
|
||||
@endif
|
||||
|
||||
<!-- login enabled -->
|
||||
<!-- login enabled -->
|
||||
<div class="row">
|
||||
<div class="col-md-3">
|
||||
{{ trans('admin/users/general.vip_label') }}
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
{!! ($user->vip=='1') ? '<i class="fas fa-check text-success" aria-hidden="true"></i> '.trans('general.yes') : '<i class="fas fa-times text-danger" aria-hidden="true"></i> '.trans('general.no') !!}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- login enabled -->
|
||||
<div class="row">
|
||||
<div class="col-md-3">
|
||||
{{ trans('admin/users/general.remote') }}
|
||||
|
|
|
@ -1162,6 +1162,17 @@ Route::group(['prefix' => 'v1', 'middleware' => ['api', 'throttle:api']], functi
|
|||
)->name('api.activity.index');
|
||||
}); // end reports api routes
|
||||
|
||||
/**
|
||||
* Version API routes
|
||||
*/
|
||||
|
||||
Route::get('/version', function () {
|
||||
return response()->json(
|
||||
[
|
||||
'version' => config('version.app_version'),
|
||||
], 200);
|
||||
}); // end version api routes
|
||||
|
||||
|
||||
Route::fallback(function () {
|
||||
return response()->json(
|
||||
|
@ -1172,5 +1183,4 @@ Route::group(['prefix' => 'v1', 'middleware' => ['api', 'throttle:api']], functi
|
|||
], 404);
|
||||
}); // end fallback routes
|
||||
|
||||
|
||||
}); // end API routes
|
||||
|
|
|
@ -40,22 +40,36 @@ Route::group(['middleware' => 'auth'], function () {
|
|||
'parameters' => ['category' => 'category_id'],
|
||||
]);
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Locations
|
||||
*/
|
||||
* Locations
|
||||
*/
|
||||
|
||||
Route::group(['prefix' => 'locations', 'middleware' => ['auth']], function () {
|
||||
|
||||
Route::get('{locationId}/clone',
|
||||
[LocationsController::class, 'getClone']
|
||||
)->name('clone/license');
|
||||
|
||||
Route::get(
|
||||
'{locationId}/printassigned',
|
||||
[LocationsController::class, 'print_assigned']
|
||||
)->name('locations.print_assigned');
|
||||
|
||||
Route::get(
|
||||
'{locationId}/printallassigned',
|
||||
[LocationsController::class, 'print_all_assigned']
|
||||
)->name('locations.print_all_assigned');
|
||||
});
|
||||
|
||||
Route::resource('locations', LocationsController::class, [
|
||||
'parameters' => ['location' => 'location_id'],
|
||||
]);
|
||||
|
||||
Route::get(
|
||||
'locations/{locationId}/printassigned',
|
||||
[LocationsController::class, 'print_assigned']
|
||||
)->name('locations.print_assigned');
|
||||
|
||||
Route::get(
|
||||
'locations/{locationId}/printallassigned',
|
||||
[LocationsController::class, 'print_all_assigned']
|
||||
)->name('locations.print_all_assigned');
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Manufacturers
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load diff
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue