Merge branch 'develop'

This commit is contained in:
snipe 2018-07-05 15:40:07 -07:00
commit b850d47282
34 changed files with 207 additions and 52 deletions

View file

@ -965,6 +965,15 @@
"contributions": [ "contributions": [
"code" "code"
] ]
},
{
"login": "plexorama",
"name": "plexorama",
"avatar_url": "https://avatars1.githubusercontent.com/u/605167?v=4",
"profile": "https://github.com/plexorama",
"contributions": [
"code"
]
} }
] ]
} }

View file

@ -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) [![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-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) [![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 ## 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://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://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://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 --> <!-- ALL-CONTRIBUTORS-LIST:END -->
This project follows the [all-contributors](https://github.com/kentcdodds/all-contributors) specification. Contributions of any kind welcome! This project follows the [all-contributors](https://github.com/kentcdodds/all-contributors) specification. Contributions of any kind welcome!

View file

@ -413,7 +413,7 @@ class Helper
{ {
$keys = array_keys(CustomField::$PredefinedFormats); $keys = array_keys(CustomField::$PredefinedFormats);
$stuff = array_combine($keys, $keys); $stuff = array_combine($keys, $keys);
return $stuff+["" => trans('admin/custom_fields/general.custom_format')]; return $stuff;
} }
/** /**

View file

@ -320,4 +320,17 @@ class UsersController extends Controller
return response()->json(['message' => 'No ID provided'], 500); 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());
}
} }

View file

@ -400,6 +400,10 @@ class ReportsController extends Controller
$header[] = 'Employee No.'; $header[] = 'Employee No.';
} }
if ($request->has('manager')) {
$header[] = trans('admin/users/table.manager');
}
if ($request->has('department')) { if ($request->has('department')) {
$header[] = trans('general.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 ($request->has('department')) {
if ($asset->checkedOutToUser()) { if ($asset->checkedOutToUser()) {

View file

@ -22,8 +22,8 @@ class Kernel extends HttpKernel
\App\Http\Middleware\ReferrerPolicyHeader::class, \App\Http\Middleware\ReferrerPolicyHeader::class,
\App\Http\Middleware\ContentSecurityPolicyHeader::class, \App\Http\Middleware\ContentSecurityPolicyHeader::class,
\App\Http\Middleware\NosniffGuard::class, \App\Http\Middleware\NosniffGuard::class,
\App\Http\Middleware\CheckForSetup::class,
\Fideloper\Proxy\TrustProxies::class, \Fideloper\Proxy\TrustProxies::class,
\App\Http\Middleware\CheckForSetup::class,
\App\Http\Middleware\CheckForDebug::class, \App\Http\Middleware\CheckForDebug::class,
// \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class, // \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
]; ];

View file

@ -9,13 +9,13 @@ use App\Helpers\Helper;
class StatuslabelsTransformer class StatuslabelsTransformer
{ {
public function transformStatuslabels (Collection $statuslabels) public function transformStatuslabels (Collection $statuslabels, $total)
{ {
$array = array(); $array = array();
foreach ($statuslabels as $statuslabel) { foreach ($statuslabels as $statuslabel) {
$array[] = self::transformStatuslabel($statuslabel); $array[] = self::transformStatuslabel($statuslabel);
} }
return (new DatatablesTransformer)->transformDatatables($array); return (new DatatablesTransformer)->transformDatatables($array, $total);
} }
public function transformStatuslabel (Statuslabel $statuslabel) public function transformStatuslabel (Statuslabel $statuslabel)

View file

@ -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. // We need to save the user if it exists so that we can checkout to user later.
// Sanitizing the item will remove it. // Sanitizing the item will remove it.
if(array_key_exists('user', $this->item)) { if(array_key_exists('checkout_target', $this->item)) {
$user = $this->item['user']; $target = $this->item['checkout_target'];
} }
$item = $this->sanitizeItemForStoring($asset, $editingAsset); $item = $this->sanitizeItemForStoring($asset, $editingAsset);
// The location id fetched by the csv reader is actually the rtd_location_id. // 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'); $asset->logCreate('Imported using csv importer');
$this->log('Asset ' . $this->item["name"] . ' with serial number ' . $this->item['serial'] . ' was created'); $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 we have a target to checkout to, lets do so.
if(isset($user)) { if(isset($target)) {
$asset->fresh()->checkOut($user); $asset->fresh()->checkOut($target);
} }
return; return;
} }

View file

@ -14,17 +14,18 @@ class ConsumableImporter extends ItemImporter
protected function handle($row) protected function handle($row)
{ {
parent::handle($row); // TODO: Change the autogenerated stub parent::handle($row);
$this->createConsumableIfNotExists(); $this->createConsumableIfNotExists($row);
} }
/** /**
* Create a consumable if a duplicate does not exist * Create a consumable if a duplicate does not exist
* *
* @author Daniel Melzter * @author Daniel Melzter
* @param array $row CSV Row Being parsed.
* @since 3.0 * @since 3.0
*/ */
public function createConsumableIfNotExists() public function createConsumableIfNotExists($row)
{ {
$consumable = Consumable::where('name', $this->item['name'])->first(); $consumable = Consumable::where('name', $this->item['name'])->first();
if ($consumable) { if ($consumable) {
@ -39,6 +40,8 @@ class ConsumableImporter extends ItemImporter
} }
$this->log("No matching consumable, creating one"); $this->log("No matching consumable, creating one");
$consumable = new Consumable(); $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)); $consumable->fill($this->sanitizeItemForStoring($consumable));
//FIXME: this disables model validation. Need to find a way to avoid double-logs without breaking everything. //FIXME: this disables model validation. Need to find a way to avoid double-logs without breaking everything.
$consumable->unsetEventDispatcher(); $consumable->unsetEventDispatcher();

View file

@ -30,8 +30,11 @@ abstract class Importer
private $defaultFieldMap = [ private $defaultFieldMap = [
'asset_tag' => 'asset tag', 'asset_tag' => 'asset tag',
'category' => 'category', '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', 'company' => 'company',
'item_name' => 'item name', 'item_name' => 'item name',
'item_number' => "item number",
'image' => 'image', 'image' => 'image',
'expiration_date' => 'expiration date', 'expiration_date' => 'expiration date',
'location' => 'location', 'location' => 'location',
@ -89,11 +92,12 @@ abstract class Importer
public function __construct($file) public function __construct($file)
{ {
$this->fieldMap = $this->defaultFieldMap; $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")) { if (! ini_get("auto_detect_line_endings")) {
ini_set("auto_detect_line_endings", '1'); 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)) { if (is_file($file)) {
$this->csv = Reader::createFromPath($file); $this->csv = Reader::createFromPath($file);
} else { } else {
@ -179,9 +183,8 @@ abstract class Importer
*/ */
public function lookupCustomKey($key) public function lookupCustomKey($key)
{ {
// dd($this->fieldMap);
if (array_key_exists($key, $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]; return $this->fieldMap[$key];
} }
// Otherwise no custom key, return original. // 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 * @param $results
* @return array * @return array
*/ */
@ -249,11 +254,11 @@ abstract class Importer
$last_name = ''; $last_name = '';
if(empty($user_name) && empty($user_email) && empty($user_username)) { if(empty($user_name) && empty($user_email) && empty($user_username)) {
$this->log('No user data provided - skipping user creation, just adding asset'); $this->log('No user data provided - skipping user creation, just adding asset');
//$user_username = '';
return false; return false;
} }
// A username was given.
if( !empty($user_username)) { if( !empty($user_username)) {
// A username was given.
$user = User::where('username', $user_username)->first(); $user = User::where('username', $user_username)->first();
if($user) { if($user) {
return $user; return $user;

View file

@ -69,11 +69,36 @@ class ItemImporter extends Importer
$this->item['serial'] = $this->findCsvMatch($row, "serial"); $this->item['serial'] = $this->findCsvMatch($row, "serial");
// NO need to call this method if we're running the user import. // NO need to call this method if we're running the user import.
// TODO: Merge these methods. // TODO: Merge these methods.
$this->item['checkout_class'] = $this->findCsvMatch($row, "checkout_class");
if(get_class($this) !== UserImporter::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. * Cleanup the $item array before storing.
* We need to remove any values that are not part of the fillable fields. * We need to remove any values that are not part of the fillable fields.

View file

@ -71,11 +71,11 @@ class LicenseImporter extends ItemImporter
// Lets try to checkout seats if the fields exist and we have seats. // Lets try to checkout seats if the fields exist and we have seats.
if ($license->seats > 0) { if ($license->seats > 0) {
$user = $this->item['user']; $checkout_target = $this->item['checkout_target'];
$asset = Asset::where('asset_tag', $asset_tag)->first(); $asset = Asset::where('asset_tag', $asset_tag)->first();
$targetLicense = $license->licenseSeats()->first(); $targetLicense = $license->licenseSeats()->first();
if ($user) { if ($checkout_target) {
$targetLicense->assigned_to = $user->id; $targetLicense->assigned_to = $checkout_target->id;
if ($asset) { if ($asset) {
$targetLicense->asset_id = $asset->id; $targetLicense->asset_id = $asset->id;
} }

View file

@ -16,6 +16,7 @@ class CustomField extends Model
public $guarded=["id"]; public $guarded=["id"];
public static $PredefinedFormats=[ public static $PredefinedFormats=[
"ANY" => "", "ANY" => "",
"CUSTOM REGEX" => "",
"ALPHA" => "alpha", "ALPHA" => "alpha",
"ALPHA-DASH" => "alpha_dash", "ALPHA-DASH" => "alpha_dash",
"NUMERIC" => "numeric", "NUMERIC" => "numeric",

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

Binary file not shown.

View file

@ -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/AdminLTE.css": "/css/AdminLTE.css?id=5e72463a66acbcc740d5",
"/css/app.css": "/css/app.css?id=407edb63cc6b6dc62405", "/css/app.css": "/css/app.css?id=407edb63cc6b6dc62405",
"/css/overrides.css": "/css/overrides.css?id=d85394a0b4f58e81bb78", "/css/overrides.css": "/css/overrides.css?id=2d81c3704393bac77011",
"/js/build/vue.js.map": "/js/build/vue.js.map?id=e0eb0edc0b761965973f", "/js/build/vue.js.map": "/js/build/vue.js.map?id=525260f84ea83d4b55cd",
"/css/AdminLTE.css.map": "/css/AdminLTE.css.map?id=99f5a5a03c4155cf69f6", "/css/AdminLTE.css.map": "/css/AdminLTE.css.map?id=99f5a5a03c4155cf69f6",
"/css/app.css.map": "/css/app.css.map?id=bdbe05e6ecd70ccfac72", "/css/app.css.map": "/css/app.css.map?id=bdbe05e6ecd70ccfac72",
"/css/overrides.css.map": "/css/overrides.css.map?id=898c91d4a425b01b589b", "/css/overrides.css.map": "/css/overrides.css.map?id=898c91d4a425b01b589b",
"/css/dist/all.css": "/css/dist/all.css?id=0e3642f1b6a8a436d558", "/css/dist/all.css": "/css/dist/all.css?id=98db4e9b7650453c8b00",
"/js/dist/all.js": "/js/dist/all.js?id=39b95992f478d68c44a8", "/js/dist/all.js": "/js/dist/all.js?id=85c7dab4c75f53c45b91",
"/css/build/all.css": "/css/build/all.css?id=0e3642f1b6a8a436d558", "/css/build/all.css": "/css/build/all.css?id=98db4e9b7650453c8b00",
"/js/build/all.js": "/js/build/all.js?id=39b95992f478d68c44a8" "/js/build/all.js": "/js/build/all.js?id=85c7dab4c75f53c45b91"
} }

View file

@ -44,8 +44,10 @@
</div> </div>
<div class="col-sm-12 col-lg-6"> <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 + ']'"> <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 + ']'"> <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> <option v-for="field_value in field.field_values_array" :value="field_value" :selected="getValue(field) == field_value">{{ field_value }}</option>
</select> </select>
</div> </div>

View file

@ -117,12 +117,18 @@ tr {
assets: [ assets: [
{id: 'asset_tag', text: 'Asset Tag' }, {id: 'asset_tag', text: 'Asset Tag' },
{id: 'asset_model', text: 'Model Name' }, {id: 'asset_model', text: 'Model Name' },
{id: 'checkout_class', text: 'Checkout Type' },
{id: 'checkout_location', text: 'Checkout Location' },
{id: 'image', text: 'Image Filename' }, {id: 'image', text: 'Image Filename' },
{id: 'model_number', text: 'Model Number' }, {id: 'model_number', text: 'Model Number' },
{id: 'full_name', text: 'Full Name' }, {id: 'full_name', text: 'Full Name' },
{id: 'status', text: 'Status' }, {id: 'status', text: 'Status' },
{id: 'warranty_months', text: 'Warranty Months' }, {id: 'warranty_months', text: 'Warranty Months' },
], ],
consumables: [
{id: 'item_no', text: "Item Number"},
{id: 'model_number', text: "Model Number"},
],
licenses: [ licenses: [
{id: 'expiration_date', text: 'Expiration Date' }, {id: 'expiration_date', text: 'Expiration Date' },
{id: 'license_email', text: 'Licensed To Email' }, {id: 'license_email', text: 'Licensed To Email' },
@ -165,6 +171,11 @@ tr {
.concat(this.columnOptions.assets) .concat(this.columnOptions.assets)
.concat(this.columnOptions.customFields) .concat(this.columnOptions.customFields)
.sort(sorter); .sort(sorter);
case 'consumable':
return this.columnOptions.general
.concat(this.columnOptions.consumables)
.sort(sorter);
case 'license': case 'license':
return this.columnOptions.general.concat(this.columnOptions.licenses).sort(sorter); return this.columnOptions.general.concat(this.columnOptions.licenses).sort(sorter);
case 'user': case 'user':
@ -184,7 +195,6 @@ tr {
}, },
watch: { watch: {
columns() { columns() {
console.log("CHANGED");
this.populateSelect2ActiveItems(); this.populateSelect2ActiveItems();
} }
}, },
@ -234,7 +244,6 @@ tr {
for(var j=0; j < this.columns.length; j++) { for(var j=0; j < this.columns.length; j++) {
let column = this.columns[j]; let column = this.columns[j];
let lower = this.file.header_row.map((value) => value.toLowerCase()); let lower = this.file.header_row.map((value) => value.toLowerCase());
console.dir(lower);
let index = lower.indexOf(column.text.toLowerCase()) let index = lower.indexOf(column.text.toLowerCase())
if(index != -1) { if(index != -1) {
this.$set(this.columnMappings, this.file.header_row[index], column.id) this.$set(this.columnMappings, this.file.header_row[index], column.id)
@ -248,7 +257,6 @@ tr {
} }
}, },
updateModel(header, value) { updateModel(header, value) {
console.log(header, value);
this.columnMappings[header] = value; this.columnMappings[header] = value;
} }
}, },

View file

@ -341,3 +341,9 @@ img.navbar-brand-img, .navbar-brand>img {
font-size: 20px; font-size: 20px;
color: #889195; color: #889195;
} }
#login-logo {
padding-top: 20px;
padding-bottom: 10px;
max-width: 200px
}

View file

@ -504,6 +504,7 @@ Form::macro('customfield_elements', function ($name = "customfield_elements", $s
$formats = array( $formats = array(
'text' => 'Text Box', 'text' => 'Text Box',
'listbox' => 'List Box', 'listbox' => 'List Box',
'textarea' => 'Textarea (multi-line) ',
// 'checkbox' => 'Checkbox', // 'checkbox' => 'Checkbox',
// 'radio' => 'Radio Buttons', // 'radio' => 'Radio Buttons',
); );

View file

@ -167,7 +167,7 @@
// Only display the custom format field if it's a custom format validation type // Only display the custom format field if it's a custom format validation type
$(".format").change(function(){ $(".format").change(function(){
$(this).find("option:selected").each(function(){ $(this).find("option:selected").each(function(){
if (($(this).attr("value")=="") && $('.format').prop("selectedIndex") != 0) { if ($('.format').prop("selectedIndex") == 1) {
$("#custom_regex").show(); $("#custom_regex").show();
} else{ } else{
$("#custom_regex").hide(); $("#custom_regex").hide();
@ -178,7 +178,7 @@
// Only display the field element if the type is not text // Only display the field element if the type is not text
$(".field_element").change(function(){ $(".field_element").change(function(){
$(this).find("option:selected").each(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(); $("#field_values_text").show();
} else{ } else{
$("#field_values_text").hide(); $("#field_values_text").hide();

View file

@ -281,7 +281,7 @@
@if (($field->format=='URL') && ($asset->{$field->db_column_name()}!='')) @if (($field->format=='URL') && ($asset->{$field->db_column_name()}!=''))
<a href="{{ $asset->{$field->db_column_name()} }}" target="_new">{{ $asset->{$field->db_column_name()} }}</a> <a href="{{ $asset->{$field->db_column_name()} }}" target="_new">{{ $asset->{$field->db_column_name()} }}</a>
@else @else
{{ $asset->{$field->db_column_name()} }} {!! nl2br(e($asset->{$field->db_column_name()})) !!}
@endif @endif
@endif @endif
</td> </td>

View file

@ -46,7 +46,7 @@
@if (($snipeSettings) && ($snipeSettings->logo!='')) @if (($snipeSettings) && ($snipeSettings->logo!=''))
<center> <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> </center>
@endif @endif
<!-- Content --> <!-- Content -->

View file

@ -224,7 +224,7 @@
@can('create', \App\Models\Component::class) @can('create', \App\Models\Component::class)
<li {!! (Request::is('components/create') ? 'class="active"' : '') !!}> <li {!! (Request::is('components/create') ? 'class="active"' : '') !!}>
<a href="{{ route('components.create') }}"> <a href="{{ route('components.create') }}">
<i class="fa fa-hdd-o"></i> <i class="fa fa-hdd-o fa-fw"></i>
{{ trans('general.component') }} {{ trans('general.component') }}
</a> </a>
</li> </li>
@ -310,7 +310,7 @@
<li {!! (Request::is('account/requested') ? ' class="active"' : '') !!}> <li {!! (Request::is('account/requested') ? ' class="active"' : '') !!}>
<a href="{{ route('account.requested') }}"> <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 Requested Assets
</a></li> </a></li>

View file

@ -4,12 +4,17 @@
<label for="{{ $field->db_column_name() }}" class="col-md-3 control-label">{{ $field->name }} </label> <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' : '' }}"> <div class="col-md-7 col-sm-12{{ ($field->pivot->required=='1') ? ' required' : '' }}">
@if ($field->element!='text') @if ($field->element!='text')
<!-- Listbox --> <!-- Listbox -->
@if ($field->element=='listbox') @if ($field->element=='listbox')
{{ Form::select($field->db_column_name(), $field->formatFieldValuesAsArray(), {{ 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']) }} 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') @elseif ($field->element=='checkbox')
<!-- Checkboxes --> <!-- Checkboxes -->
@foreach ($field->formatFieldValuesAsArray() as $key => $value) @foreach ($field->formatFieldValuesAsArray() as $key => $value)

View file

@ -49,8 +49,7 @@
<fieldset-default-values <fieldset-default-values
model-id="{{ $item->id ?: '' }}" model-id="{{ $item->id ?: '' }}"
fieldset-id="{{ !empty($item->fieldset) ? $item->fieldset->id : Input::old('custom_fieldset') }}" 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> </fieldset-default-values>
</div> </div>

View file

@ -221,6 +221,13 @@
</label> </label>
</div> </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"> <div class="checkbox col-md-12">
<label> <label>
{{ Form::checkbox('department', '1', '1', ['class' => 'minimal']) }} {{ Form::checkbox('department', '1', '1', ['class' => 'minimal']) }}
@ -231,6 +238,7 @@
@if ($customfields->count() > 0) @if ($customfields->count() > 0)
<div class="checkbox col-md-12"> <div class="checkbox col-md-12">
<h4>Custom Fields:</h4> <h4>Custom Fields:</h4>

View file

@ -674,8 +674,8 @@ Route::group(['prefix' => 'v1','namespace' => 'Api'], function () {
/*--- Users API ---*/
/*--- Users API ---*/
Route::group([ 'prefix' => 'users' ], function () { Route::group([ 'prefix' => 'users' ], function () {
@ -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?}', Route::get('list/{status?}',
[ [
'as' => 'api.users.list', 'as' => 'api.users.list',

View file

@ -8,6 +8,7 @@ use App\Models\Asset;
use App\Models\AssetModel; use App\Models\AssetModel;
use App\Models\Category; use App\Models\Category;
use App\Models\CustomField; use App\Models\CustomField;
use App\Models\Location;
use App\Models\User; use App\Models\User;
use Illuminate\Foundation\Testing\DatabaseMigrations; use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions; use Illuminate\Foundation\Testing\DatabaseTransactions;
@ -72,12 +73,61 @@ EOT;
'asset_tag' => '970882174-8', '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.", '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_date' => '2016-04-05 00:00:01',
'purchase_cost' => 133289.59, 'purchase_cost' => 133289.59
'warranty_months' => 14, , 'warranty_months' => 14,
'_snipeit_weight_2' => 35 '_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() public function testUpdateAssetIncludingCustomFields()
{ {
$this->signIn(); $this->signIn();
@ -385,18 +435,19 @@ EOT;
public function testDefaultConsumableImport() public function testDefaultConsumableImport()
{ {
$csv = <<<'EOT' $csv = <<<'EOT'
Item Name,Purchase Date,Purchase Cost,Location,Company,Order Number,Category,Requestable,Quantity 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 eget,01/03/2011,$85.91,mauris blandit mattis.,Lycos,T295T06V,Triamterene/Hydrochlorothiazide,No,322,3305,30123
EOT; EOT;
$this->import(new ConsumableImporter($csv)); $this->import(new ConsumableImporter($csv));
$this->tester->seeRecord('consumables', [ $this->tester->seeRecord('consumables', [
'name' => 'eget', 'name' => 'eget',
'purchase_date' => '2011-01-03 00:00:01', 'purchase_date' => '2011-01-03 00:00:01',
'purchase_cost' => 85.91, 'purchase_cost' => 85.91,
'order_number' => 'T295T06V', 'order_number' => 'T295T06V',
'requestable' => 0, 'requestable' => 0,
'qty' => 322 'qty' => 322,
'item_no' => 3305,
'model_number' => 30123
]); ]);
$this->tester->seeRecord('locations', [ $this->tester->seeRecord('locations', [