mirror of
https://github.com/snipe/snipe-it.git
synced 2024-12-25 21:54:14 -08:00
Merge branch 'develop'
This commit is contained in:
commit
b850d47282
|
@ -965,6 +965,15 @@
|
|||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "plexorama",
|
||||
"name": "plexorama",
|
||||
"avatar_url": "https://avatars1.githubusercontent.com/u/605167?v=4",
|
||||
"profile": "https://github.com/plexorama",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
[![Build Status](https://travis-ci.org/snipe/snipe-it.svg?branch=master)](https://travis-ci.org/snipe/snipe-it) [![Crowdin](https://d322cqt584bo4o.cloudfront.net/snipe-it/localized.svg)](https://crowdin.com/project/snipe-it) [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/snipe/snipe-it?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![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/snipeyhead.svg?style=social)](https://twitter.com/snipeyhead) [![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-104-orange.svg?style=flat-square)](#contributors) [![Open Source Helpers](https://www.codetriage.com/snipe/snipe-it/badges/users.svg)](https://www.codetriage.com/snipe/snipe-it)
|
||||
[![Build Status](https://travis-ci.org/snipe/snipe-it.svg?branch=master)](https://travis-ci.org/snipe/snipe-it) [![Crowdin](https://d322cqt584bo4o.cloudfront.net/snipe-it/localized.svg)](https://crowdin.com/project/snipe-it) [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/snipe/snipe-it?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![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-105-orange.svg?style=flat-square)](#contributors) [![Open Source Helpers](https://www.codetriage.com/snipe/snipe-it/badges/users.svg)](https://www.codetriage.com/snipe/snipe-it)
|
||||
|
||||
|
||||
## Snipe-IT - Open Source Asset Management System
|
||||
|
@ -83,7 +83,7 @@ Thanks goes to all of these wonderful people ([emoji key](https://github.com/ken
|
|||
| [<img src="https://avatars2.githubusercontent.com/u/2809241?v=4" width="110px;"/><br /><sub>Robin Temme</sub>](https://github.com/zwerch)<br />[💻](https://github.com/snipe/snipe-it/commits?author=zwerch "Code") | [<img src="https://avatars0.githubusercontent.com/u/6961695?v=4" width="110px;"/><br /><sub>Iman</sub>](https://github.com/imanghafoori1)<br />[💻](https://github.com/snipe/snipe-it/commits?author=imanghafoori1 "Code") | [<img src="https://avatars1.githubusercontent.com/u/6551003?v=4" width="110px;"/><br /><sub>Richard Hofman</sub>](https://github.com/richardhofman6)<br />[💻](https://github.com/snipe/snipe-it/commits?author=richardhofman6 "Code") | [<img src="https://avatars0.githubusercontent.com/u/3697569?v=4" width="110px;"/><br /><sub>gizzmojr</sub>](https://github.com/gizzmojr)<br />[💻](https://github.com/snipe/snipe-it/commits?author=gizzmojr "Code") | [<img src="https://avatars3.githubusercontent.com/u/404729?v=4" width="110px;"/><br /><sub>Jenny Li</sub>](https://github.com/imjennyli)<br />[📖](https://github.com/snipe/snipe-it/commits?author=imjennyli "Documentation") | [<img src="https://avatars0.githubusercontent.com/u/869227?v=4" width="110px;"/><br /><sub>Geoff Young</sub>](https://github.com/GeoffYoung)<br />[💻](https://github.com/snipe/snipe-it/commits?author=GeoffYoung "Code") | [<img src="https://avatars3.githubusercontent.com/u/1068477?v=4" width="110px;"/><br /><sub>Elliot Blackburn</sub>](http://www.elliotblackburn.com)<br />[📖](https://github.com/snipe/snipe-it/commits?author=BlueHatbRit "Documentation") |
|
||||
| [<img src="https://avatars1.githubusercontent.com/u/6357451?v=4" width="110px;"/><br /><sub>Tõnis Ormisson</sub>](http://andmemasin.eu)<br />[💻](https://github.com/snipe/snipe-it/commits?author=TonisOrmisson "Code") | [<img src="https://avatars0.githubusercontent.com/u/449411?v=4" width="110px;"/><br /><sub>Nicolai Essig</sub>](http://www.nicolai-essig.de)<br />[💻](https://github.com/snipe/snipe-it/commits?author=thakilla "Code") | [<img src="https://avatars1.githubusercontent.com/u/14809698?v=4" width="110px;"/><br /><sub>Danielle</sub>](https://github.com/techincolor)<br />[📖](https://github.com/snipe/snipe-it/commits?author=techincolor "Documentation") | [<img src="https://avatars1.githubusercontent.com/u/18545156?v=4" width="110px;"/><br /><sub>Lawrence</sub>](https://github.com/TheVakman)<br />[⚠️](https://github.com/snipe/snipe-it/commits?author=TheVakman "Tests") [🐛](https://github.com/snipe/snipe-it/issues?q=author%3ATheVakman "Bug reports") | [<img src="https://avatars1.githubusercontent.com/u/22473767?v=4" width="110px;"/><br /><sub>uknzaeinozpas</sub>](https://github.com/uknzaeinozpas)<br />[⚠️](https://github.com/snipe/snipe-it/commits?author=uknzaeinozpas "Tests") [💻](https://github.com/snipe/snipe-it/commits?author=uknzaeinozpas "Code") | [<img src="https://avatars3.githubusercontent.com/u/422752?v=4" width="110px;"/><br /><sub>Ryan</sub>](https://github.com/Gelob)<br />[📖](https://github.com/snipe/snipe-it/commits?author=Gelob "Documentation") | [<img src="https://avatars1.githubusercontent.com/u/10672546?v=4" width="110px;"/><br /><sub>vcordes79</sub>](https://github.com/vcordes79)<br />[💻](https://github.com/snipe/snipe-it/commits?author=vcordes79 "Code") |
|
||||
| [<img src="https://avatars3.githubusercontent.com/u/27958330?v=4" width="110px;"/><br /><sub>fordster78</sub>](https://github.com/fordster78)<br />[💻](https://github.com/snipe/snipe-it/commits?author=fordster78 "Code") | [<img src="https://avatars0.githubusercontent.com/u/34064225?v=4" width="110px;"/><br /><sub>CronKz</sub>](https://github.com/CronKz)<br />[💻](https://github.com/snipe/snipe-it/commits?author=CronKz "Code") | [<img src="https://avatars1.githubusercontent.com/u/585486?v=4" width="110px;"/><br /><sub>Tim Bishop</sub>](https://github.com/tdb)<br />[💻](https://github.com/snipe/snipe-it/commits?author=tdb "Code") | [<img src="https://avatars2.githubusercontent.com/u/5384694?v=4" width="110px;"/><br /><sub>Sean McIlvenna</sub>](https://www.seanmcilvenna.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=seanmcilvenna "Code") | [<img src="https://avatars3.githubusercontent.com/u/36515590?v=4" width="110px;"/><br /><sub>cepacs</sub>](https://github.com/cepacs)<br />[🐛](https://github.com/snipe/snipe-it/issues?q=author%3Acepacs "Bug reports") [📖](https://github.com/snipe/snipe-it/commits?author=cepacs "Documentation") | [<img src="https://avatars2.githubusercontent.com/u/37537300?v=4" width="110px;"/><br /><sub>lea-mink</sub>](https://github.com/lea-mink)<br />[💻](https://github.com/snipe/snipe-it/commits?author=lea-mink "Code") | [<img src="https://avatars0.githubusercontent.com/u/7140719?v=4" width="110px;"/><br /><sub>Hannah Tinkler</sub>](https://github.com/hannahtinkler)<br />[💻](https://github.com/snipe/snipe-it/commits?author=hannahtinkler "Code") |
|
||||
| [<img src="https://avatars1.githubusercontent.com/u/1086388?v=4" width="110px;"/><br /><sub>Doeke Zanstra</sub>](https://github.com/doekman)<br />[💻](https://github.com/snipe/snipe-it/commits?author=doekman "Code") | [<img src="https://avatars1.githubusercontent.com/u/4325936?v=4" width="110px;"/><br /><sub>Djamon Staal</sub>](https://www.sdhd.nl/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=SjamonDaal "Code") | [<img src="https://avatars3.githubusercontent.com/u/12306859?v=4" width="110px;"/><br /><sub>Earl Ramirez</sub>](https://github.com/EarlRamirez)<br />[💻](https://github.com/snipe/snipe-it/commits?author=EarlRamirez "Code") | [<img src="https://avatars2.githubusercontent.com/u/8671456?v=4" width="110px;"/><br /><sub>Richard Ray Thomas</sub>](https://github.com/RichardRay)<br />[💻](https://github.com/snipe/snipe-it/commits?author=RichardRay "Code") | [<img src="https://avatars3.githubusercontent.com/u/1852688?v=4" width="110px;"/><br /><sub>Ryan Kuba</sub>](https://www.taisun.io/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=thelamer "Code") | [<img src="https://avatars1.githubusercontent.com/u/6751928?v=4" width="110px;"/><br /><sub>Brian Monroe</sub>](https://github.com/ParadoxGuitarist)<br />[💻](https://github.com/snipe/snipe-it/commits?author=ParadoxGuitarist "Code") |
|
||||
| [<img src="https://avatars1.githubusercontent.com/u/1086388?v=4" width="110px;"/><br /><sub>Doeke Zanstra</sub>](https://github.com/doekman)<br />[💻](https://github.com/snipe/snipe-it/commits?author=doekman "Code") | [<img src="https://avatars1.githubusercontent.com/u/4325936?v=4" width="110px;"/><br /><sub>Djamon Staal</sub>](https://www.sdhd.nl/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=SjamonDaal "Code") | [<img src="https://avatars3.githubusercontent.com/u/12306859?v=4" width="110px;"/><br /><sub>Earl Ramirez</sub>](https://github.com/EarlRamirez)<br />[💻](https://github.com/snipe/snipe-it/commits?author=EarlRamirez "Code") | [<img src="https://avatars2.githubusercontent.com/u/8671456?v=4" width="110px;"/><br /><sub>Richard Ray Thomas</sub>](https://github.com/RichardRay)<br />[💻](https://github.com/snipe/snipe-it/commits?author=RichardRay "Code") | [<img src="https://avatars3.githubusercontent.com/u/1852688?v=4" width="110px;"/><br /><sub>Ryan Kuba</sub>](https://www.taisun.io/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=thelamer "Code") | [<img src="https://avatars1.githubusercontent.com/u/6751928?v=4" width="110px;"/><br /><sub>Brian Monroe</sub>](https://github.com/ParadoxGuitarist)<br />[💻](https://github.com/snipe/snipe-it/commits?author=ParadoxGuitarist "Code") | [<img src="https://avatars1.githubusercontent.com/u/605167?v=4" width="110px;"/><br /><sub>plexorama</sub>](https://github.com/plexorama)<br />[💻](https://github.com/snipe/snipe-it/commits?author=plexorama "Code") |
|
||||
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
||||
|
||||
This project follows the [all-contributors](https://github.com/kentcdodds/all-contributors) specification. Contributions of any kind welcome!
|
||||
|
|
|
@ -413,7 +413,7 @@ class Helper
|
|||
{
|
||||
$keys = array_keys(CustomField::$PredefinedFormats);
|
||||
$stuff = array_combine($keys, $keys);
|
||||
return $stuff+["" => trans('admin/custom_fields/general.custom_format')];
|
||||
return $stuff;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -320,4 +320,17 @@ class UsersController extends Controller
|
|||
return response()->json(['message' => 'No ID provided'], 500);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get info on the current user.
|
||||
*
|
||||
* @author [Juan Font] [<juanfontalonso@gmail.com>]
|
||||
* @since [v4.4.2]
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function getCurrentUserInfo(Request $request)
|
||||
{
|
||||
return response()->json($request->user());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -400,6 +400,10 @@ class ReportsController extends Controller
|
|||
$header[] = 'Employee No.';
|
||||
}
|
||||
|
||||
if ($request->has('manager')) {
|
||||
$header[] = trans('admin/users/table.manager');
|
||||
}
|
||||
|
||||
if ($request->has('department')) {
|
||||
$header[] = trans('general.department');
|
||||
}
|
||||
|
@ -613,6 +617,14 @@ class ReportsController extends Controller
|
|||
}
|
||||
}
|
||||
|
||||
if ($request->has('manager')) {
|
||||
if ($asset->checkedOutToUser()) {
|
||||
$row[] = (($asset->assignedto) && ($asset->assignedto->manager)) ? $asset->assignedto->manager->present()->fullName : '';
|
||||
} else {
|
||||
$row[] = ''; // Empty string if unassigned
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ($request->has('department')) {
|
||||
if ($asset->checkedOutToUser()) {
|
||||
|
|
|
@ -22,8 +22,8 @@ class Kernel extends HttpKernel
|
|||
\App\Http\Middleware\ReferrerPolicyHeader::class,
|
||||
\App\Http\Middleware\ContentSecurityPolicyHeader::class,
|
||||
\App\Http\Middleware\NosniffGuard::class,
|
||||
\App\Http\Middleware\CheckForSetup::class,
|
||||
\Fideloper\Proxy\TrustProxies::class,
|
||||
\App\Http\Middleware\CheckForSetup::class,
|
||||
\App\Http\Middleware\CheckForDebug::class,
|
||||
// \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
|
||||
];
|
||||
|
|
|
@ -9,13 +9,13 @@ use App\Helpers\Helper;
|
|||
class StatuslabelsTransformer
|
||||
{
|
||||
|
||||
public function transformStatuslabels (Collection $statuslabels)
|
||||
public function transformStatuslabels (Collection $statuslabels, $total)
|
||||
{
|
||||
$array = array();
|
||||
foreach ($statuslabels as $statuslabel) {
|
||||
$array[] = self::transformStatuslabel($statuslabel);
|
||||
}
|
||||
return (new DatatablesTransformer)->transformDatatables($array);
|
||||
return (new DatatablesTransformer)->transformDatatables($array, $total);
|
||||
}
|
||||
|
||||
public function transformStatuslabel (Statuslabel $statuslabel)
|
||||
|
|
|
@ -81,8 +81,8 @@ class AssetImporter extends ItemImporter
|
|||
|
||||
// We need to save the user if it exists so that we can checkout to user later.
|
||||
// Sanitizing the item will remove it.
|
||||
if(array_key_exists('user', $this->item)) {
|
||||
$user = $this->item['user'];
|
||||
if(array_key_exists('checkout_target', $this->item)) {
|
||||
$target = $this->item['checkout_target'];
|
||||
}
|
||||
$item = $this->sanitizeItemForStoring($asset, $editingAsset);
|
||||
// The location id fetched by the csv reader is actually the rtd_location_id.
|
||||
|
@ -112,9 +112,9 @@ class AssetImporter extends ItemImporter
|
|||
$asset->logCreate('Imported using csv importer');
|
||||
$this->log('Asset ' . $this->item["name"] . ' with serial number ' . $this->item['serial'] . ' was created');
|
||||
|
||||
// If we have a user to checkout to, lets do so.
|
||||
if(isset($user)) {
|
||||
$asset->fresh()->checkOut($user);
|
||||
// If we have a target to checkout to, lets do so.
|
||||
if(isset($target)) {
|
||||
$asset->fresh()->checkOut($target);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -14,17 +14,18 @@ class ConsumableImporter extends ItemImporter
|
|||
|
||||
protected function handle($row)
|
||||
{
|
||||
parent::handle($row); // TODO: Change the autogenerated stub
|
||||
$this->createConsumableIfNotExists();
|
||||
parent::handle($row);
|
||||
$this->createConsumableIfNotExists($row);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a consumable if a duplicate does not exist
|
||||
*
|
||||
* @author Daniel Melzter
|
||||
* @param array $row CSV Row Being parsed.
|
||||
* @since 3.0
|
||||
*/
|
||||
public function createConsumableIfNotExists()
|
||||
public function createConsumableIfNotExists($row)
|
||||
{
|
||||
$consumable = Consumable::where('name', $this->item['name'])->first();
|
||||
if ($consumable) {
|
||||
|
@ -39,6 +40,8 @@ class ConsumableImporter extends ItemImporter
|
|||
}
|
||||
$this->log("No matching consumable, creating one");
|
||||
$consumable = new Consumable();
|
||||
$this->item['model_number'] = $this->findCsvMatch($row, "model_number");;
|
||||
$this->item['item_no'] = $this->findCsvMatch($row, "item_number");
|
||||
$consumable->fill($this->sanitizeItemForStoring($consumable));
|
||||
//FIXME: this disables model validation. Need to find a way to avoid double-logs without breaking everything.
|
||||
$consumable->unsetEventDispatcher();
|
||||
|
|
|
@ -30,8 +30,11 @@ abstract class Importer
|
|||
private $defaultFieldMap = [
|
||||
'asset_tag' => 'asset tag',
|
||||
'category' => 'category',
|
||||
'checkout_class' => 'checkout type', // Supports Location or User for assets. Using checkout_class instead of checkout_type because type exists on asset already.
|
||||
'checkout_location' => 'checkout location',
|
||||
'company' => 'company',
|
||||
'item_name' => 'item name',
|
||||
'item_number' => "item number",
|
||||
'image' => 'image',
|
||||
'expiration_date' => 'expiration date',
|
||||
'location' => 'location',
|
||||
|
@ -89,11 +92,12 @@ abstract class Importer
|
|||
public function __construct($file)
|
||||
{
|
||||
$this->fieldMap = $this->defaultFieldMap;
|
||||
// By default the importer passes a url to the file.
|
||||
// However, for testing we also support passing a string directly
|
||||
if (! ini_get("auto_detect_line_endings")) {
|
||||
ini_set("auto_detect_line_endings", '1');
|
||||
}
|
||||
|
||||
// By default the importer passes a url to the file.
|
||||
// However, for testing we also support passing a string directly
|
||||
if (is_file($file)) {
|
||||
$this->csv = Reader::createFromPath($file);
|
||||
} else {
|
||||
|
@ -179,9 +183,8 @@ abstract class Importer
|
|||
*/
|
||||
public function lookupCustomKey($key)
|
||||
{
|
||||
// dd($this->fieldMap);
|
||||
if (array_key_exists($key, $this->fieldMap)) {
|
||||
$this->log("Found a match in our custom map: {$key} is " . $this->fieldMap[$key]);
|
||||
// $this->log("Found a match in our custom map: {$key} is " . $this->fieldMap[$key]);
|
||||
return $this->fieldMap[$key];
|
||||
}
|
||||
// Otherwise no custom key, return original.
|
||||
|
@ -189,6 +192,8 @@ abstract class Importer
|
|||
}
|
||||
|
||||
/**
|
||||
* Used to lowercase header values to ensure we're comparing values properly.
|
||||
*
|
||||
* @param $results
|
||||
* @return array
|
||||
*/
|
||||
|
@ -249,11 +254,11 @@ abstract class Importer
|
|||
$last_name = '';
|
||||
if(empty($user_name) && empty($user_email) && empty($user_username)) {
|
||||
$this->log('No user data provided - skipping user creation, just adding asset');
|
||||
//$user_username = '';
|
||||
return false;
|
||||
}
|
||||
// A username was given.
|
||||
|
||||
if( !empty($user_username)) {
|
||||
// A username was given.
|
||||
$user = User::where('username', $user_username)->first();
|
||||
if($user) {
|
||||
return $user;
|
||||
|
|
|
@ -69,11 +69,36 @@ class ItemImporter extends Importer
|
|||
$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");
|
||||
if(get_class($this) !== UserImporter::class) {
|
||||
$this->item["user"] = $this->createOrFetchUser($row);
|
||||
// $this->item["user"] = $this->createOrFetchUser($row);
|
||||
$this->item["checkout_target"] = $this->determineCheckout($row);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse row to determine what (if anything) we should checkout to.
|
||||
* @param array $row CSV Row being parsed
|
||||
* @return SnipeModel Model to be checked out to
|
||||
*/
|
||||
protected function determineCheckout($row)
|
||||
{
|
||||
// We only supporty checkout-to-location for asset, so short circuit otherw.
|
||||
if(get_class($this) != AssetImporter::class) {
|
||||
return $this->createOrFetchUser($row);
|
||||
}
|
||||
|
||||
if ($this->item['checkout_class'] === 'location') {
|
||||
// dd($this->findCsvMatch($row, 'checkout_location'));
|
||||
return Location::findOrFail($this->createOrFetchLocation($this->findCsvMatch($row, 'checkout_location')));
|
||||
// dd('here');
|
||||
}
|
||||
|
||||
return $this->createOrFetchUser($row);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleanup the $item array before storing.
|
||||
* We need to remove any values that are not part of the fillable fields.
|
||||
|
|
|
@ -71,11 +71,11 @@ class LicenseImporter extends ItemImporter
|
|||
|
||||
// Lets try to checkout seats if the fields exist and we have seats.
|
||||
if ($license->seats > 0) {
|
||||
$user = $this->item['user'];
|
||||
$checkout_target = $this->item['checkout_target'];
|
||||
$asset = Asset::where('asset_tag', $asset_tag)->first();
|
||||
$targetLicense = $license->licenseSeats()->first();
|
||||
if ($user) {
|
||||
$targetLicense->assigned_to = $user->id;
|
||||
if ($checkout_target) {
|
||||
$targetLicense->assigned_to = $checkout_target->id;
|
||||
if ($asset) {
|
||||
$targetLicense->asset_id = $asset->id;
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ class CustomField extends Model
|
|||
public $guarded=["id"];
|
||||
public static $PredefinedFormats=[
|
||||
"ANY" => "",
|
||||
"CUSTOM REGEX" => "",
|
||||
"ALPHA" => "alpha",
|
||||
"ALPHA-DASH" => "alpha_dash",
|
||||
"NUMERIC" => "numeric",
|
||||
|
|
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.
BIN
public/js/dist/all.js
vendored
BIN
public/js/dist/all.js
vendored
Binary file not shown.
|
@ -1,14 +1,14 @@
|
|||
{
|
||||
"/js/build/vue.js": "/js/build/vue.js?id=992bcb968a7f2da998b5",
|
||||
"/js/build/vue.js": "/js/build/vue.js?id=5eab4676dde73dbab3ca",
|
||||
"/css/AdminLTE.css": "/css/AdminLTE.css?id=5e72463a66acbcc740d5",
|
||||
"/css/app.css": "/css/app.css?id=407edb63cc6b6dc62405",
|
||||
"/css/overrides.css": "/css/overrides.css?id=d85394a0b4f58e81bb78",
|
||||
"/js/build/vue.js.map": "/js/build/vue.js.map?id=e0eb0edc0b761965973f",
|
||||
"/css/overrides.css": "/css/overrides.css?id=2d81c3704393bac77011",
|
||||
"/js/build/vue.js.map": "/js/build/vue.js.map?id=525260f84ea83d4b55cd",
|
||||
"/css/AdminLTE.css.map": "/css/AdminLTE.css.map?id=99f5a5a03c4155cf69f6",
|
||||
"/css/app.css.map": "/css/app.css.map?id=bdbe05e6ecd70ccfac72",
|
||||
"/css/overrides.css.map": "/css/overrides.css.map?id=898c91d4a425b01b589b",
|
||||
"/css/dist/all.css": "/css/dist/all.css?id=0e3642f1b6a8a436d558",
|
||||
"/js/dist/all.js": "/js/dist/all.js?id=39b95992f478d68c44a8",
|
||||
"/css/build/all.css": "/css/build/all.css?id=0e3642f1b6a8a436d558",
|
||||
"/js/build/all.js": "/js/build/all.js?id=39b95992f478d68c44a8"
|
||||
"/css/dist/all.css": "/css/dist/all.css?id=98db4e9b7650453c8b00",
|
||||
"/js/dist/all.js": "/js/dist/all.js?id=85c7dab4c75f53c45b91",
|
||||
"/css/build/all.css": "/css/build/all.css?id=98db4e9b7650453c8b00",
|
||||
"/js/build/all.js": "/js/build/all.js?id=85c7dab4c75f53c45b91"
|
||||
}
|
|
@ -44,8 +44,10 @@
|
|||
</div>
|
||||
<div class="col-sm-12 col-lg-6">
|
||||
<input v-if="field.type == 'text'" class="form-control m-b-xs" type="text" :value="getValue(field)" :id="'default-value' + field.id" :name="'default_values[' + field.id + ']'">
|
||||
<textarea v-if="field.type == 'textarea'" class="form-control" :value="getValue(field)" :id="'default-value' + field.id" :name="'default_values[' + field.id + ']'"></textarea><br>
|
||||
|
||||
<select v-if="field.type == 'listbox'" class="form-control m-b-xs" :name="'default_values[' + field.id + ']'">
|
||||
<option value="0"></option>
|
||||
<option value=""></option>
|
||||
<option v-for="field_value in field.field_values_array" :value="field_value" :selected="getValue(field) == field_value">{{ field_value }}</option>
|
||||
</select>
|
||||
</div>
|
||||
|
|
|
@ -117,12 +117,18 @@ tr {
|
|||
assets: [
|
||||
{id: 'asset_tag', text: 'Asset Tag' },
|
||||
{id: 'asset_model', text: 'Model Name' },
|
||||
{id: 'checkout_class', text: 'Checkout Type' },
|
||||
{id: 'checkout_location', text: 'Checkout Location' },
|
||||
{id: 'image', text: 'Image Filename' },
|
||||
{id: 'model_number', text: 'Model Number' },
|
||||
{id: 'full_name', text: 'Full Name' },
|
||||
{id: 'status', text: 'Status' },
|
||||
{id: 'warranty_months', text: 'Warranty Months' },
|
||||
],
|
||||
consumables: [
|
||||
{id: 'item_no', text: "Item Number"},
|
||||
{id: 'model_number', text: "Model Number"},
|
||||
],
|
||||
licenses: [
|
||||
{id: 'expiration_date', text: 'Expiration Date' },
|
||||
{id: 'license_email', text: 'Licensed To Email' },
|
||||
|
@ -165,6 +171,11 @@ tr {
|
|||
.concat(this.columnOptions.assets)
|
||||
.concat(this.columnOptions.customFields)
|
||||
.sort(sorter);
|
||||
|
||||
case 'consumable':
|
||||
return this.columnOptions.general
|
||||
.concat(this.columnOptions.consumables)
|
||||
.sort(sorter);
|
||||
case 'license':
|
||||
return this.columnOptions.general.concat(this.columnOptions.licenses).sort(sorter);
|
||||
case 'user':
|
||||
|
@ -184,7 +195,6 @@ tr {
|
|||
},
|
||||
watch: {
|
||||
columns() {
|
||||
console.log("CHANGED");
|
||||
this.populateSelect2ActiveItems();
|
||||
}
|
||||
},
|
||||
|
@ -234,7 +244,6 @@ tr {
|
|||
for(var j=0; j < this.columns.length; j++) {
|
||||
let column = this.columns[j];
|
||||
let lower = this.file.header_row.map((value) => value.toLowerCase());
|
||||
console.dir(lower);
|
||||
let index = lower.indexOf(column.text.toLowerCase())
|
||||
if(index != -1) {
|
||||
this.$set(this.columnMappings, this.file.header_row[index], column.id)
|
||||
|
@ -248,7 +257,6 @@ tr {
|
|||
}
|
||||
},
|
||||
updateModel(header, value) {
|
||||
console.log(header, value);
|
||||
this.columnMappings[header] = value;
|
||||
}
|
||||
},
|
||||
|
|
|
@ -341,3 +341,9 @@ img.navbar-brand-img, .navbar-brand>img {
|
|||
font-size: 20px;
|
||||
color: #889195;
|
||||
}
|
||||
|
||||
#login-logo {
|
||||
padding-top: 20px;
|
||||
padding-bottom: 10px;
|
||||
max-width: 200px
|
||||
}
|
||||
|
|
|
@ -504,6 +504,7 @@ Form::macro('customfield_elements', function ($name = "customfield_elements", $s
|
|||
$formats = array(
|
||||
'text' => 'Text Box',
|
||||
'listbox' => 'List Box',
|
||||
'textarea' => 'Textarea (multi-line) ',
|
||||
// 'checkbox' => 'Checkbox',
|
||||
// 'radio' => 'Radio Buttons',
|
||||
);
|
||||
|
|
|
@ -167,7 +167,7 @@
|
|||
// Only display the custom format field if it's a custom format validation type
|
||||
$(".format").change(function(){
|
||||
$(this).find("option:selected").each(function(){
|
||||
if (($(this).attr("value")=="") && $('.format').prop("selectedIndex") != 0) {
|
||||
if ($('.format').prop("selectedIndex") == 1) {
|
||||
$("#custom_regex").show();
|
||||
} else{
|
||||
$("#custom_regex").hide();
|
||||
|
@ -178,7 +178,7 @@
|
|||
// Only display the field element if the type is not text
|
||||
$(".field_element").change(function(){
|
||||
$(this).find("option:selected").each(function(){
|
||||
if($(this).attr("value")!="text"){
|
||||
if (($(this).attr("value")!="text") && ($(this).attr("value")!="textarea")){
|
||||
$("#field_values_text").show();
|
||||
} else{
|
||||
$("#field_values_text").hide();
|
||||
|
|
|
@ -281,7 +281,7 @@
|
|||
@if (($field->format=='URL') && ($asset->{$field->db_column_name()}!=''))
|
||||
<a href="{{ $asset->{$field->db_column_name()} }}" target="_new">{{ $asset->{$field->db_column_name()} }}</a>
|
||||
@else
|
||||
{{ $asset->{$field->db_column_name()} }}
|
||||
{!! nl2br(e($asset->{$field->db_column_name()})) !!}
|
||||
@endif
|
||||
@endif
|
||||
</td>
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
|
||||
@if (($snipeSettings) && ($snipeSettings->logo!=''))
|
||||
<center>
|
||||
<img style="padding-top: 20px; padding-bottom: 10px; max-width: 150px" src="{{ url('/') }}/uploads/{{ $snipeSettings->logo }}">
|
||||
<img id="login-logo" src="{{ url('/') }}/uploads/{{ $snipeSettings->logo }}">
|
||||
</center>
|
||||
@endif
|
||||
<!-- Content -->
|
||||
|
|
|
@ -224,7 +224,7 @@
|
|||
@can('create', \App\Models\Component::class)
|
||||
<li {!! (Request::is('components/create') ? 'class="active"' : '') !!}>
|
||||
<a href="{{ route('components.create') }}">
|
||||
<i class="fa fa-hdd-o"></i>
|
||||
<i class="fa fa-hdd-o fa-fw"></i>
|
||||
{{ trans('general.component') }}
|
||||
</a>
|
||||
</li>
|
||||
|
@ -310,7 +310,7 @@
|
|||
|
||||
<li {!! (Request::is('account/requested') ? ' class="active"' : '') !!}>
|
||||
<a href="{{ route('account.requested') }}">
|
||||
<i class="fa fa-check fa-disk"></i>
|
||||
<i class="fa fa-check fa-disk fa-fw"></i>
|
||||
Requested Assets
|
||||
</a></li>
|
||||
|
||||
|
|
|
@ -4,12 +4,17 @@
|
|||
<label for="{{ $field->db_column_name() }}" class="col-md-3 control-label">{{ $field->name }} </label>
|
||||
<div class="col-md-7 col-sm-12{{ ($field->pivot->required=='1') ? ' required' : '' }}">
|
||||
|
||||
|
||||
@if ($field->element!='text')
|
||||
<!-- Listbox -->
|
||||
@if ($field->element=='listbox')
|
||||
{{ Form::select($field->db_column_name(), $field->formatFieldValuesAsArray(),
|
||||
Input::old($field->db_column_name(),(isset($item) ? $item->{$field->db_column_name()} : $field->defaultValue($model->id))), ['class'=>'format select2 form-control']) }}
|
||||
|
||||
@elseif ($field->element=='textarea')
|
||||
<textarea class="col-md-6 form-control" id="{{ $field->db_column_name() }}" name="{{ $field->db_column_name() }}">{{ Input::old($field->db_column_name(),(isset($item) ? $item->{$field->db_column_name()} : $field->defaultValue($model->id))) }}</textarea>
|
||||
|
||||
|
||||
@elseif ($field->element=='checkbox')
|
||||
<!-- Checkboxes -->
|
||||
@foreach ($field->formatFieldValuesAsArray() as $key => $value)
|
||||
|
|
|
@ -49,8 +49,7 @@
|
|||
<fieldset-default-values
|
||||
model-id="{{ $item->id ?: '' }}"
|
||||
fieldset-id="{{ !empty($item->fieldset) ? $item->fieldset->id : Input::old('custom_fieldset') }}"
|
||||
previous-input="{{ json_encode(Input::old('default_values')) }}"
|
||||
>
|
||||
previous-input="{{ json_encode(Input::old('default_values')) }}">
|
||||
</fieldset-default-values>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -221,6 +221,13 @@
|
|||
</label>
|
||||
</div>
|
||||
|
||||
<div class="checkbox col-md-12">
|
||||
<label>
|
||||
{{ Form::checkbox('manager', '1', '1', ['class' => 'minimal']) }}
|
||||
{{ trans('admin/users/table.manager') }}
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="checkbox col-md-12">
|
||||
<label>
|
||||
{{ Form::checkbox('department', '1', '1', ['class' => 'minimal']) }}
|
||||
|
@ -231,6 +238,7 @@
|
|||
|
||||
|
||||
|
||||
|
||||
@if ($customfields->count() > 0)
|
||||
<div class="checkbox col-md-12">
|
||||
<h4>Custom Fields:</h4>
|
||||
|
|
|
@ -674,10 +674,10 @@ Route::group(['prefix' => 'v1','namespace' => 'Api'], function () {
|
|||
|
||||
|
||||
|
||||
|
||||
/*--- Users API ---*/
|
||||
|
||||
|
||||
|
||||
|
||||
Route::group([ 'prefix' => 'users' ], function () {
|
||||
|
||||
Route::post('two_factor_reset',
|
||||
|
@ -687,6 +687,13 @@ Route::group(['prefix' => 'v1','namespace' => 'Api'], function () {
|
|||
]
|
||||
);
|
||||
|
||||
Route::get('me',
|
||||
[
|
||||
'as' => 'api.users.me',
|
||||
'uses' => 'UsersController@getCurrentUserInfo'
|
||||
]
|
||||
);
|
||||
|
||||
Route::get('list/{status?}',
|
||||
[
|
||||
'as' => 'api.users.list',
|
||||
|
|
|
@ -8,6 +8,7 @@ use App\Models\Asset;
|
|||
use App\Models\AssetModel;
|
||||
use App\Models\Category;
|
||||
use App\Models\CustomField;
|
||||
use App\Models\Location;
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Testing\DatabaseMigrations;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
@ -72,12 +73,61 @@ EOT;
|
|||
'asset_tag' => '970882174-8',
|
||||
'notes' => "Curabitur in libero ut massa volutpat convallis. Morbi odio odio, elementum eu, interdum eu, tincidunt in, leo. Maecenas pulvinar lobortis est.",
|
||||
'purchase_date' => '2016-04-05 00:00:01',
|
||||
'purchase_cost' => 133289.59,
|
||||
'warranty_months' => 14,
|
||||
'purchase_cost' => 133289.59
|
||||
, 'warranty_months' => 14,
|
||||
'_snipeit_weight_2' => 35
|
||||
]);
|
||||
}
|
||||
|
||||
public function testImportCheckoutToLocation()
|
||||
{
|
||||
$this->signIn();
|
||||
|
||||
// Testing in order:
|
||||
// * Asset to user, no checkout type defined (default to user).
|
||||
// * Asset to user, explicit user checkout type (Checkout to user)
|
||||
// * Asset to location, location does not exist to begin with
|
||||
// * Asset to preexisting location.
|
||||
$csv = <<<'EOT'
|
||||
Full Name,Email,Username,Checkout Location,Checkout Type,item Name,Category,Model name,Manufacturer,Model Number,Serial,Asset Tag,Location,Notes,Purchase Date,Purchase Cost,Company,Status,Warranty,Supplier,Weight
|
||||
Bonnie Nelson,bnelson0@cdbaby.com,bnelson0,,,eget nunc donec quis,quam,massa id,Linkbridge,6377018600094472,27aa8378-b0f4-4289-84a4-405da95c6147,970882174-8,Daping,"Curabitur in libero ut massa volutpat convallis. Morbi odio odio, elementum eu, interdum eu, tincidunt in, leo. Maecenas pulvinar lobortis est.",2016-04-05,133289.59,Alpha,Undeployable,14,Blogspan,35
|
||||
Mildred Gibson,mgibson2@wiley.com,mgibson2,,user,morbi quis tortor id,nunc nisl duis,convallis tortor risus,Lajo,374622546776765,2837ab20-8f0d-4935-8a52-226392f2b1b0,710141467-2,Shekou,In congue. Etiam justo. Etiam pretium iaculis justo.,2015-08-09,233.57,Konklab,Lost,,,
|
||||
,,,Planet Earth,location,dictumst maecenas ut,sem praesent,accumsan felis,Layo,30052522651756,4751495c-cee0-4961-b788-94a545b5643e,998233705-X,Dante Delgado,,2016-04-16,261.79,,Archived,15,Ntag,
|
||||
,,,Daping,location,viverra diam vitae,semper sapien,dapibus dolor vel,Flashset,3559785746335392,e287bb64-ff4f-434c-88ab-210ad433c77b,927820758-6,Achiaman,,2016-03-05,675.3,,Archived,22,Meevee,
|
||||
EOT;
|
||||
|
||||
$this->import(new AssetImporter($csv));
|
||||
$user = User::where('username', 'bnelson0')->firstOrFail();
|
||||
|
||||
$this->tester->seeRecord('assets', [
|
||||
'asset_tag' => '970882174-8',
|
||||
'assigned_type' => User::class,
|
||||
'assigned_to' => $user->id
|
||||
]);
|
||||
|
||||
$user = User::where('username', 'mgibson2')->firstOrFail();
|
||||
$this->tester->seeRecord('assets', [
|
||||
'asset_tag' => '710141467-2',
|
||||
'assigned_type' => User::class,
|
||||
'assigned_to' => $user->id
|
||||
]);
|
||||
|
||||
$location = Location::where('name', 'Planet Earth')->firstOrFail();
|
||||
$this->tester->seeRecord('assets', [
|
||||
'asset_tag' => '998233705-X',
|
||||
'assigned_type' => Location::class,
|
||||
'assigned_to' => $location->id
|
||||
]);
|
||||
|
||||
$location = Location::where('name', 'Daping')->firstOrFail();
|
||||
$this->tester->seeRecord('assets', [
|
||||
'asset_tag' => '927820758-6',
|
||||
'assigned_type' => Location::class,
|
||||
'assigned_to' => $location->id
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
public function testUpdateAssetIncludingCustomFields()
|
||||
{
|
||||
$this->signIn();
|
||||
|
@ -385,18 +435,19 @@ EOT;
|
|||
public function testDefaultConsumableImport()
|
||||
{
|
||||
$csv = <<<'EOT'
|
||||
Item Name,Purchase Date,Purchase Cost,Location,Company,Order Number,Category,Requestable,Quantity
|
||||
eget,01/03/2011,$85.91,mauris blandit mattis.,Lycos,T295T06V,Triamterene/Hydrochlorothiazide,No,322
|
||||
Item Name,Purchase Date,Purchase Cost,Location,Company,Order Number,Category,Requestable,Quantity,Item Number,Model Number
|
||||
eget,01/03/2011,$85.91,mauris blandit mattis.,Lycos,T295T06V,Triamterene/Hydrochlorothiazide,No,322,3305,30123
|
||||
EOT;
|
||||
$this->import(new ConsumableImporter($csv));
|
||||
|
||||
$this->tester->seeRecord('consumables', [
|
||||
'name' => 'eget',
|
||||
'purchase_date' => '2011-01-03 00:00:01',
|
||||
'purchase_cost' => 85.91,
|
||||
'order_number' => 'T295T06V',
|
||||
'requestable' => 0,
|
||||
'qty' => 322
|
||||
'qty' => 322,
|
||||
'item_no' => 3305,
|
||||
'model_number' => 30123
|
||||
]);
|
||||
|
||||
$this->tester->seeRecord('locations', [
|
||||
|
|
Loading…
Reference in a new issue