Merge branch 'develop'

This commit is contained in:
snipe 2018-01-09 20:12:44 -08:00
commit 6245f92e16
32 changed files with 112 additions and 47 deletions

View file

@ -344,7 +344,7 @@ class AssetsController extends Controller
$asset->model_id = $request->get('model_id');
$asset->order_number = $request->get('order_number');
$asset->notes = $request->get('notes');
$asset->asset_tag = $request->get('asset_tag');
$asset->asset_tag = $request->get('asset_tag', Asset::autoincrement_asset());
$asset->user_id = Auth::id();
$asset->archived = '0';
$asset->physical = '1';

View file

@ -36,13 +36,16 @@ class AssetRequest extends Request
'checkin_date' => 'date',
'supplier_id' => 'integer|nullable',
'status' => 'integer|nullable',
'asset_tag' => 'required',
'purchase_cost' => 'numeric|nullable',
"assigned_user" => 'sometimes:required_without_all:assigned_asset,assigned_location',
"assigned_asset" => 'sometimes:required_without_all:assigned_user,assigned_location',
"assigned_location" => 'sometimes:required_without_all:assigned_user,assigned_asset',
];
$settings = \App\Models\Setting::getSettings();
$rules['asset_tag'] = ($settings->auto_increment_assets == '1') ? 'max:255' : 'required';
$model = AssetModel::find($this->request->get('model_id'));
if (($model) && ($model->fieldset)) {

View file

@ -26,7 +26,7 @@ class ItemImportRequest extends FormRequest
public function rules()
{
return [
//
'import-type' => 'required',
];
}

View file

@ -41,6 +41,7 @@ class AccessoryImporter extends ItemImporter
$this->log("No Matching Accessory, Creating a new one");
$accessory = new Accessory();
$accessory->fill($this->sanitizeItemForStoring($accessory));
$accessory->unsetEventDispatcher();
if ($accessory->save()) {
$accessory->logCreate('Imported using CSV Importer');
$this->log('Accessory ' . $this->item["name"] . ' was created');

View file

@ -79,28 +79,42 @@ class AssetImporter extends ItemImporter
}
$this->item['asset_tag'] = $asset_tag;
// 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'];
}
$item = $this->sanitizeItemForStoring($asset, $editingAsset);
// By default we're set this to location_id in the item.
// The location id fetched by the csv reader is actually the rtd_location_id.
// This will also set location_id, but then that will be overridden by the
// checkout method if necessary below.
if (isset($this->item["location_id"])) {
$item['rtd_location_id'] = $this->item['location_id'];
unset($item['location_id']);
}
if ($editingAsset) {
$asset->update($item);
} else {
$asset->fill($item);
}
// If we're updating, we don't want to overwrite old fields.
// If we're updating, we don't want to overwrite old fields.
if (array_key_exists('custom_fields', $this->item)) {
foreach ($this->item['custom_fields'] as $custom_field => $val) {
$asset->{$custom_field} = $val;
}
}
$asset->unsetEventDispatcher();
if ($asset->save()) {
$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);
}
return;
}
$this->logError($asset, 'Asset "' . $this->item['name'].'"');

View file

@ -27,27 +27,26 @@ class ComponentImporter extends ItemImporter
public function createComponentIfNotExists()
{
$component = null;
$editingComponent = false;
$this->log("Creating Component");
$component = Component::where('name', $this->item['name']);
$component = Component::where('name', $this->item['name'])
->where('serial', $this->item['serial'])
->first();
if ($component) {
$editingComponent = true;
$this->log('A matching Component ' . $this->item["name"] . ' already exists. ');
$this->log('A matching Component ' . $this->item["name"] . ' with serial ' .$this->item['serial'].' already exists. ');
if (!$this->updating) {
$this->log("Skipping Component");
return;
}
$this->log("Updating Component");
$component = $this->components[$componentId];
$component->update($this->sanitizeItemFor($component));
$component->update($this->sanitizeItemForUpdating($component));
$component->save();
return;
}
$this->log("No matching component, creating one");
$component = new Component;
$component->fill($$this->sanitizeItemForStoring($component));
$component->fill($this->sanitizeItemForStoring($component));
$component->unsetEventDispatcher();
if ($component->save()) {
$component->logCreate('Imported using CSV Importer');
$this->log("Component " . $this->item["name"] . ' was created');

View file

@ -41,6 +41,7 @@ class ConsumableImporter extends ItemImporter
$consumable = new Consumable();
$consumable->fill($this->sanitizeItemForStoring($consumable));
$consumable->unsetEventDispatcher();
if ($consumable->save()) {
$consumable->logCreate('Imported using CSV Importer');
$this->log("Consumable " . $this->item["name"] . ' was created');

View file

@ -239,12 +239,15 @@ abstract class Importer
// A number was given instead of a name
if (is_numeric($user_name)) {
$this->log('User '.$user_name.' is not a name - assume this user already exists');
$user_username = '';
// No name was given
$user = User::find($user_name);
if($user) {
return $user;
}
$this->log('User with id'.$user_name.' does not exist. Continuing through our processes');
} elseif (empty($user_name)) {
$this->log('No user data provided - skipping user creation, just adding asset');
//$user_username = '';
return false;
} else {
$user_email_array = User::generateFormattedNameFromFullName(Setting::getSettings()->email_format, $user_name);
$first_name = $user_email_array['first_name'];

View file

@ -67,10 +67,7 @@ class ItemImporter extends Importer
// NO need to call this method if we're running the user import.
// TODO: Merge these methods.
if(get_class($this) !== UserImporter::class) {
if ($this->item["user"] = $this->createOrFetchUser($row)) {
$this->item['assigned_to'] = $this->item['user']->id;
$this->item['assigned_type'] = User::class;
}
$this->item["user"] = $this->createOrFetchUser($row);
}
}

View file

@ -63,6 +63,8 @@ class LicenseImporter extends ItemImporter
} else {
$license->fill($this->sanitizeItemForStoring($license));
}
$license->unsetEventDispatcher();
if ($license->save()) {
$license->logCreate('Imported using csv importer');
$this->log('License ' . $this->item["name"] . ' with serial number ' . $this->item['serial'] . ' was created');

View file

@ -33,7 +33,7 @@ class UserImporter extends ItemImporter
$this->item['username'] = $this->findCsvMatch($row, 'username');
$this->item['first_name'] = $this->findCsvMatch($row, 'first_name');
$this->item['last_name'] = $this->findCsvMatch($row, 'last_name');
$this->item['email'] = $this->findCsvMatch($row, 'user_email');
$this->item['email'] = $this->findCsvMatch($row, 'email');
$this->item['phone'] = $this->findCsvMatch($row, 'phone_number');
$this->item['jobtitle'] = $this->findCsvMatch($row, 'jobtitle');
$this->item['employee_num'] = $this->findCsvMatch($row, 'employee_num');

View file

@ -12,6 +12,7 @@ use Illuminate\Database\Eloquent\SoftDeletes;
use Log;
use Watson\Validating\ValidatingTrait;
use Illuminate\Notifications\Notifiable;
use DB;
/**
* Model for Assets.
@ -173,6 +174,10 @@ class Asset extends Depreciable
if ($location != null) {
$this->location_id = $location;
} else {
if($target->location) {
$this->location_id = $target->location->id;
}
}
if ($this->requireAcceptance()) {
@ -814,7 +819,7 @@ class Asset extends Depreciable
})->orWhere(function ($query) use ($search) {
$query->where('assets_users.first_name', 'LIKE', '%'.$search.'%')
->orWhere('assets_users.last_name', 'LIKE', '%'.$search.'%')
->orWhereRaw('CONCAT(assets_users.first_name," ",assets_users.last_name) LIKE ?', ["%$search%", "%$search%"])
->orWhereRaw('CONCAT('.DB::getTablePrefix().'assets_users.first_name," ",'.DB::getTablePrefix().'assets_users.last_name) LIKE ?', ["%$search%", "%$search%"])
->orWhere('assets_users.username', 'LIKE', '%'.$search.'%')
->orWhere('assets_locations.name', 'LIKE', '%'.$search.'%')
->orWhere('assigned_assets.name', 'LIKE', '%'.$search.'%');
@ -873,7 +878,7 @@ class Asset extends Depreciable
})->orWhere(function ($query) use ($search) {
$query->where('assets_users.first_name', 'LIKE', '%'.$search.'%')
->orWhere('assets_users.last_name', 'LIKE', '%'.$search.'%')
->orWhereRaw('CONCAT(assets_users.first_name," ",assets_users.last_name) LIKE ?', ["%$search%", "%$search%"])
->orWhereRaw('CONCAT('.DB::getTablePrefix().'assets_users.first_name," ",'.DB::getTablePrefix().'assets_users.last_name) LIKE ?', ["%$search%", "%$search%"])
->orWhere('assets_users.username', 'LIKE', '%'.$search.'%')
->orWhere('assets_locations.name', 'LIKE', '%'.$search.'%')
->orWhere('assigned_assets.name', 'LIKE', '%'.$search.'%');

View file

@ -55,6 +55,7 @@ class Component extends SnipeModel
'purchase_date',
'min_amt',
'qty',
'serial'
];
public function location()

View file

@ -182,7 +182,7 @@ trait Loggable
$log->location_id = null;
$log->note = $note;
$log->user_id = $user_id;
$log->logaction('created');
$log->logaction('create');
$log->save();
return $log;
}

View file

@ -14,9 +14,10 @@
"babel-preset-latest": "^6.24.1",
"cross-env": "^5.0.5",
"jquery": "^3.1.1",
"laravel-mix": "1.4.3",
"laravel-mix": "1.7",
"lodash": "^4.17.4",
"vue": "2.4.4",
"vue-loader": "^13.6.1",
"vue-template-compiler": "2.4.4"
},
"dependencies": {

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

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

Binary file not shown.

View file

@ -1,14 +1,10 @@
{
"/js/build/vue.js": "/js/build/vue.js?id=e6804371942215bd1d7d",
"/css/AdminLTE.css": "/css/AdminLTE.css?id=b8be19a285eaf44eec37",
"/css/app.css": "/css/app.css?id=407edb63cc6b6dc62405",
"/css/overrides.css": "/css/overrides.css?id=1bdafb06a8609780f546",
"/js/build/vue.js.map": "/js/build/vue.js.map?id=3b3d417664a61dcce3e9",
"/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=3a8aa974e7b09b52b18c",
"/js/dist/all.js": "/js/dist/all.js?id=88f08e0103b14f7949b3",
"/css/build/all.css": "/css/build/all.css?id=3a8aa974e7b09b52b18c",
"/js/build/all.js": "/js/build/all.js?id=88f08e0103b14f7949b3"
"/js/build/vue.js": "/js/build/vue.js?id=32ce13a589cb455849de",
"/css/AdminLTE.css": "/css/AdminLTE.css?id=889dc040f2ddfca6efde",
"/css/app.css": "/css/app.css?id=3a1e8c168fa8714043a6",
"/css/overrides.css": "/css/overrides.css?id=21c1a4ba652c6546f14b",
"/css/dist/all.css": "/css/dist/all.css?id=9bf6e85e322473238339",
"/js/dist/all.js": "/js/dist/all.js?id=254a99c7a1ccaa032f2f",
"/css/build/all.css": "/css/build/all.css?id=9bf6e85e322473238339",
"/js/build/all.js": "/js/build/all.js?id=254a99c7a1ccaa032f2f"
}

View file

@ -13,7 +13,7 @@ tr {
<label for="import-type">Import Type:</label>
</div>
<div class="col-md-4 col-xs-12">
<select2 :options="options.importTypes" v-model="options.importType">
<select2 :options="options.importTypes" v-model="options.importType" required>
<option disabled value="0"></option>
</select2>
</div>
@ -60,7 +60,14 @@ tr {
<td>
<button type="button" class="btn btn-sm btn-default" @click="processDetail = false">Cancel</button>
<button type="submit" class="btn btn-sm btn-primary" @click="postSave">Import</button>
<div class="alert alert-success col-md-5 col-md-offset-1" style="text-align:left" v-if="statusText">{{ this.statusText }}</div>
<div
class="alert col-md-5 col-md-offset-1"
:class="alertClass"
style="text-align:left"
v-if="statusText"
>
{{ this.statusText }}
</div>
</td>
</tr>
</template>
@ -73,6 +80,7 @@ tr {
activeFile: this.file,
processDetail: false,
statusText: null,
statusType: null,
options: {
importType: this.file.import_type,
update: false,
@ -151,10 +159,33 @@ tr {
return this.columnOptions.general.concat(this.columnOptions.users);
}
return this.columnOptions.general;
},
alertClass() {
if(this.statusType=='success') {
return 'alert-success';
}
if(this.statusType=='error') {
return 'alert-danger';
}
return 'alert-info';
},
},
watch: {
columns() {
console.log("CHANGED");
this.populateSelect2ActiveItems();
}
},
methods: {
postSave() {
console.log('saving');
console.log(this.options.importType);
if(!this.options.importType) {
this.statusType='error';
this.statusText= "An import type is required... ";
return;
}
this.statusType='pending';
this.statusText = "Processing...";
this.$http.post(route('api.imports.importFile', this.file.id), {
'import-update': this.options.update,
@ -162,12 +193,14 @@ tr {
'column-mappings': this.columnMappings
}).then( ({body}) => {
// Success
this.statusType="success";
this.statusText = "Success... Redirecting.";
window.location.href = body.messages.redirect_url;
}, ({body}) => {
// Failure
if(body.status == 'import-errors') {
window.eventHub.$emit('importErrors', body.messages);
this.statusType='error';
this.statusText = "Error";
} else {
this.$emit('alert', {
@ -188,7 +221,9 @@ tr {
// Then, for any values that have a likely match, we make that active.
for(var j=0; j < this.columns.length; j++) {
let column = this.columns[j];
let index = this.file.header_row.indexOf(column.text)
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)
}

View file

@ -712,7 +712,7 @@
</td>
<td>
@can('update', \App\Models\Asset::class)
<a class="btn delete-asset btn-danger btn-sm" href="{{ route('delete/assetfile', [$asset->id, $file->id]) }}"><i class="fa fa-trash icon-white"></i></a>
<a class="btn delete-asset btn-danger btn-sm" href="{{ route('delete/assetfile', [$asset->id, $file->id]) }}" data-tooltip="true" data-title="Delete" data-content="Are you sure you wish to delete {{$file->filename}}"><i class="fa fa-trash icon-white"></i></a>
@endcan
</td>
</tr>

View file

@ -166,6 +166,13 @@
</li>
@endif
@if ($model->notes)
<li>
{{ trans('general.notes') }}:
{{ $model->notes }}
</li>
@endif
@if ($model->deleted_at!='')

View file

@ -3,9 +3,12 @@
<div class="col-md-5">
<label class="btn btn-default">
{{ trans('button.select_file') }}
<input type="file" name="image" accept="image/gif,image/jpeg,image/png,image/svg" hidden>
<input type="file" name="image" accept="image/gif,image/jpeg,image/png,image/svg"
onchange="$('#upload-file-info').html(this.files[0].name)" style="display:none">
</label>
<span class='label label-default' id="upload-file-info"></span>
<p class="help-block">{{ trans('general.image_filetypes_help') }}</p>
{!! $errors->first('image', '<span class="alert-msg">:message</span>') !!}
</div>
</div>

View file

@ -35,7 +35,7 @@ mix
).sourceMaps()
.scripts([
'./node_modules/jquery-ui/jquery-ui.js',
'./public/build/vue.js', //this is the modularized nifty Vue.js thing we just built, above!
'./public/js/build/vue.js', //this is the modularized nifty Vue.js thing we just built, above!
'./node_modules/tether/dist/js/tether.min.js',
'./node_modules/jquery-slimscroll/jquery.slimscroll.js',
'./node_modules/jquery.iframe-transport/jquery.iframe-transport.js',