Merge branch 'develop' into snipeit_v7_laravel10

Upgraded composer due to lockfile conflicts
This commit is contained in:
Brady Wetherington 2023-08-28 16:04:21 +01:00
commit 427f8b1522
42 changed files with 1012 additions and 429 deletions

View file

@ -234,17 +234,39 @@ class LdapSync extends Command
$item['createorupdate'] = 'created'; $item['createorupdate'] = 'created';
} }
$user->first_name = $item['firstname']; //If a sync option is not filled in on the LDAP settings don't populate the user field
$user->last_name = $item['lastname']; if($ldap_result_username != null){
$user->username = $item['username']; $user->username = $item['username'];
$user->email = $item['email']; }
if($ldap_result_last_name != null){
$user->last_name = $item['lastname'];
}
if($ldap_result_first_name != null){
$user->first_name = $item['firstname'];
}
if($ldap_result_emp_num != null){
$user->employee_num = e($item['employee_number']); $user->employee_num = e($item['employee_number']);
}
if($ldap_result_email != null){
$user->email = $item['email'];
}
if($ldap_result_phone != null){
$user->phone = $item['telephone']; $user->phone = $item['telephone'];
}
if($ldap_result_jobtitle != null){
$user->jobtitle = $item['jobtitle']; $user->jobtitle = $item['jobtitle'];
}
if($ldap_result_country != null){
$user->country = $item['country']; $user->country = $item['country'];
}
if($ldap_result_dept != null){
$user->department_id = $department->id; $user->department_id = $department->id;
}
if($ldap_result_location != null){
$user->location_id = $location ? $location->id : null; $user->location_id = $location ? $location->id : null;
}
if($ldap_result_manager != null){
if($item['manager'] != null) { if($item['manager'] != null) {
// Check Cache first // Check Cache first
if (isset($manager_cache[$item['manager']])) { if (isset($manager_cache[$item['manager']])) {
@ -284,6 +306,7 @@ class LdapSync extends Command
} }
} }
}
// Sync activated state for Active Directory. // Sync activated state for Active Directory.
if ( !empty($ldap_result_active_flag)) { // IF we have an 'active' flag set.... if ( !empty($ldap_result_active_flag)) { // IF we have an 'active' flag set....

View file

@ -69,7 +69,7 @@ class AcceptanceController extends Controller
} }
if (! Company::isCurrentUserHasAccess($acceptance->checkoutable)) { if (! Company::isCurrentUserHasAccess($acceptance->checkoutable)) {
return redirect()->route('account.accept')->with('error', trans('general.insufficient_permissions')); return redirect()->route('account.accept')->with('error', trans('general.error_user_company'));
} }
return view('account/accept.create', compact('acceptance')); return view('account/accept.create', compact('acceptance'));
@ -245,6 +245,36 @@ class AcceptanceController extends Controller
$return_msg = trans('admin/users/message.accepted'); $return_msg = trans('admin/users/message.accepted');
} else { } else {
/**
* Check for the eula-pdfs directory
*/
if (! Storage::exists('private_uploads/eula-pdfs')) {
Storage::makeDirectory('private_uploads/eula-pdfs', 775);
}
if (Setting::getSettings()->require_accept_signature == '1') {
// Check if the signature directory exists, if not create it
if (!Storage::exists('private_uploads/signatures')) {
Storage::makeDirectory('private_uploads/signatures', 775);
}
// The item was accepted, check for a signature
if ($request->filled('signature_output')) {
$sig_filename = 'siglog-' . Str::uuid() . '-' . date('Y-m-d-his') . '.png';
$data_uri = $request->input('signature_output');
$encoded_image = explode(',', $data_uri);
$decoded_image = base64_decode($encoded_image[1]);
Storage::put('private_uploads/signatures/' . $sig_filename, (string)$decoded_image);
// No image data is present, kick them back.
// This mostly only applies to users on super-duper crapola browsers *cough* IE *cough*
} else {
return redirect()->back()->with('error', trans('general.shitty_browser'));
}
}
// Format the data to send the declined notification // Format the data to send the declined notification
$branding_settings = SettingsController::getPDFBranding(); $branding_settings = SettingsController::getPDFBranding();
@ -281,11 +311,18 @@ class AcceptanceController extends Controller
'item_model' => $display_model, 'item_model' => $display_model,
'item_serial' => $item->serial, 'item_serial' => $item->serial,
'declined_date' => Carbon::parse($acceptance->declined_at)->format('Y-m-d'), 'declined_date' => Carbon::parse($acceptance->declined_at)->format('Y-m-d'),
'signature' => ($sig_filename) ? storage_path() . '/private_uploads/signatures/' . $sig_filename : null,
'assigned_to' => $assigned_to, 'assigned_to' => $assigned_to,
'company_name' => $branding_settings->site_name, 'company_name' => $branding_settings->site_name,
'date_settings' => $branding_settings->date_display_format, 'date_settings' => $branding_settings->date_display_format,
]; ];
if ($pdf_view_route!='') {
\Log::debug($pdf_filename.' is the filename, and the route was specified.');
$pdf = Pdf::loadView($pdf_view_route, $data);
Storage::put('private_uploads/eula-pdfs/' .$pdf_filename, $pdf->output());
}
$acceptance->decline($sig_filename); $acceptance->decline($sig_filename);
$acceptance->notify(new AcceptanceAssetDeclinedNotification($data)); $acceptance->notify(new AcceptanceAssetDeclinedNotification($data));
event(new CheckoutDeclined($acceptance)); event(new CheckoutDeclined($acceptance));

View file

@ -331,7 +331,7 @@ class AccessoriesController extends Controller
$accessory = Accessory::find($accessory_user->accessory_id); $accessory = Accessory::find($accessory_user->accessory_id);
$this->authorize('checkin', $accessory); $this->authorize('checkin', $accessory);
$logaction = $accessory->logCheckin(User::find($accessory_user->user_id), $request->input('note')); $logaction = $accessory->logCheckin(User::find($accessory_user->assigned_to), $request->input('note'));
// Was the accessory updated? // Was the accessory updated?
if (DB::table('accessories_users')->where('id', '=', $accessory_user->id)->delete()) { if (DB::table('accessories_users')->where('id', '=', $accessory_user->id)->delete()) {

View file

@ -13,6 +13,7 @@ use App\Events\CheckoutableCheckedIn;
use App\Events\ComponentCheckedIn; use App\Events\ComponentCheckedIn;
use App\Models\Asset; use App\Models\Asset;
use Illuminate\Support\Facades\Validator; use Illuminate\Support\Facades\Validator;
use Illuminate\Database\Query\Builder;
class ComponentsController extends Controller class ComponentsController extends Controller
{ {
@ -203,12 +204,29 @@ class ComponentsController extends Controller
$this->authorize('view', \App\Models\Asset::class); $this->authorize('view', \App\Models\Asset::class);
$component = Component::findOrFail($id); $component = Component::findOrFail($id);
$assets = $component->assets();
$offset = request('offset', 0); $offset = request('offset', 0);
$limit = $request->input('limit', 50); $limit = $request->input('limit', 50);
$total = $assets->count();
$assets = $assets->skip($offset)->take($limit)->get(); if ($request->filled('search')) {
$assets = $component->assets()
->where(function ($query) use ($request) {
$search_str = '%' . $request->input('search') . '%';
$query->where('name', 'like', $search_str)
->orWhereIn('model_id', function (Builder $query) use ($request) {
$search_str = '%' . $request->input('search') . '%';
$query->selectRaw('id')->from('models')->where('name', 'like', $search_str);
})
->orWhere('asset_tag', 'like', $search_str);
})
->get();
$total = $assets->count();
} else {
$assets = $component->assets();
$total = $assets->count();
$assets = $assets->skip($offset)->take($limit)->get();
}
return (new ComponentsTransformer)->transformCheckedoutComponents($assets, $total); return (new ComponentsTransformer)->transformCheckedoutComponents($assets, $total);
} }

View file

@ -41,7 +41,7 @@ class SuppliersController extends Controller
]; ];
$suppliers = Supplier::select( $suppliers = Supplier::select(
['id', 'name', 'address', 'address2', 'city', 'state', 'country', 'fax', 'phone', 'email', 'contact', 'created_at', 'updated_at', 'deleted_at', 'image', 'notes']) ['id', 'name', 'address', 'address2', 'city', 'state', 'country', 'fax', 'phone', 'email', 'contact', 'created_at', 'updated_at', 'deleted_at', 'image', 'notes', 'url'])
->withCount('assets as assets_count') ->withCount('assets as assets_count')
->withCount('licenses as licenses_count') ->withCount('licenses as licenses_count')
->withCount('accessories as accessories_count') ->withCount('accessories as accessories_count')

View file

@ -89,6 +89,14 @@ class AssetCheckoutController extends Controller
} }
} }
$settings = \App\Models\Setting::getSettings();
if ($settings->full_multiple_companies_support){
if ($target->company_id != $asset->company_id){
return redirect()->to("hardware/$assetId/checkout")->with('error', trans('general.error_user_company'));
}
}
if ($asset->checkOut($target, $admin, $checkout_at, $expected_checkin, e($request->get('note')), $request->get('name'))) { if ($asset->checkOut($target, $admin, $checkout_at, $expected_checkin, e($request->get('note')), $request->get('name'))) {
return redirect()->route('hardware.index')->with('success', trans('admin/hardware/message.checkout.success')); return redirect()->route('hardware.index')->with('success', trans('admin/hardware/message.checkout.success'));
} }

View file

@ -14,6 +14,7 @@ use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Session; use Illuminate\Support\Facades\Session;
use App\Http\Requests\AssetCheckoutRequest; use App\Http\Requests\AssetCheckoutRequest;
use App\Models\CustomField;
class BulkAssetsController extends Controller class BulkAssetsController extends Controller
{ {
@ -31,7 +32,7 @@ class BulkAssetsController extends Controller
public function edit(Request $request) public function edit(Request $request)
{ {
$this->authorize('view', Asset::class); $this->authorize('view', Asset::class);
if (! $request->filled('ids')) { if (! $request->filled('ids')) {
return redirect()->back()->with('error', trans('admin/hardware/message.update.no_assets_selected')); return redirect()->back()->with('error', trans('admin/hardware/message.update.no_assets_selected'));
} }
@ -41,6 +42,17 @@ class BulkAssetsController extends Controller
session(['bulk_back_url' => $bulk_back_url]); session(['bulk_back_url' => $bulk_back_url]);
$asset_ids = array_values(array_unique($request->input('ids'))); $asset_ids = array_values(array_unique($request->input('ids')));
//custom fields logic
$asset_custom_field = Asset::with(['model.fieldset.fields', 'model'])->whereIn('id', $asset_ids)->whereHas('model', function ($query) {
return $query->where('fieldset_id', '!=', null);
})->get();
$models = $asset_custom_field->unique('model_id');
$modelNames = [];
foreach($models as $model) {
$modelNames[] = $model->model->name;
}
if ($request->filled('bulk_actions')) { if ($request->filled('bulk_actions')) {
switch ($request->input('bulk_actions')) { switch ($request->input('bulk_actions')) {
@ -74,7 +86,9 @@ class BulkAssetsController extends Controller
$this->authorize('update', Asset::class); $this->authorize('update', Asset::class);
return view('hardware/bulk') return view('hardware/bulk')
->with('assets', $asset_ids) ->with('assets', $asset_ids)
->with('statuslabel_list', Helper::statusLabelList()); ->with('statuslabel_list', Helper::statusLabelList())
->with('models', $models->pluck(['model']))
->with('modelNames', $modelNames);
} }
} }
@ -92,6 +106,7 @@ class BulkAssetsController extends Controller
public function update(Request $request) public function update(Request $request)
{ {
$this->authorize('update', Asset::class); $this->authorize('update', Asset::class);
$error_bag = [];
// Get the back url from the session and then destroy the session // Get the back url from the session and then destroy the session
$bulk_back_url = route('hardware.index'); $bulk_back_url = route('hardware.index');
@ -100,12 +115,21 @@ class BulkAssetsController extends Controller
} }
if (! $request->filled('ids') || count($request->input('ids')) <= 0) { $custom_field_columns = CustomField::all()->pluck('db_column')->toArray();
if(Session::exists('ids')) {
$assets = Session::get('ids');
} elseif (! $request->filled('ids') || count($request->input('ids')) <= 0) {
return redirect($bulk_back_url)->with('error', trans('admin/hardware/message.update.no_assets_selected')); return redirect($bulk_back_url)->with('error', trans('admin/hardware/message.update.no_assets_selected'));
} }
$assets = array_keys($request->input('ids')); $assets = array_keys($request->input('ids'));
if ($request->anyFilled($custom_field_columns)) {
$custom_fields_present = true;
} else {
$custom_fields_present = false;
}
if (($request->filled('purchase_date')) if (($request->filled('purchase_date'))
|| ($request->filled('expected_checkin')) || ($request->filled('expected_checkin'))
|| ($request->filled('purchase_cost')) || ($request->filled('purchase_cost'))
@ -121,6 +145,7 @@ class BulkAssetsController extends Controller
|| ($request->filled('null_purchase_date')) || ($request->filled('null_purchase_date'))
|| ($request->filled('null_expected_checkin_date')) || ($request->filled('null_expected_checkin_date'))
|| ($request->filled('null_next_audit_date')) || ($request->filled('null_next_audit_date'))
|| ($request->anyFilled($custom_field_columns))
) { ) {
foreach ($assets as $assetId) { foreach ($assets as $assetId) {
@ -136,6 +161,9 @@ class BulkAssetsController extends Controller
->conditionallyAddItem('supplier_id') ->conditionallyAddItem('supplier_id')
->conditionallyAddItem('warranty_months') ->conditionallyAddItem('warranty_months')
->conditionallyAddItem('next_audit_date'); ->conditionallyAddItem('next_audit_date');
foreach ($custom_field_columns as $key => $custom_field_column) {
$this->conditionallyAddItem($custom_field_column);
}
if ($request->input('null_purchase_date')=='1') { if ($request->input('null_purchase_date')=='1') {
$this->update_array['purchase_date'] = null; $this->update_array['purchase_date'] = null;
@ -168,11 +196,11 @@ class BulkAssetsController extends Controller
} }
$changed = []; $changed = [];
$asset = Asset::where('id' ,$assetId)->get(); $assetCollection = Asset::where('id' ,$assetId)->get();
foreach ($this->update_array as $key => $value) { foreach ($this->update_array as $key => $value) {
if ($this->update_array[$key] != $asset->toArray()[0][$key]) { if ($this->update_array[$key] != $assetCollection->toArray()[0][$key]) {
$changed[$key]['old'] = $asset->toArray()[0][$key]; $changed[$key]['old'] = $assetCollection->toArray()[0][$key];
$changed[$key]['new'] = $this->update_array[$key]; $changed[$key]['new'] = $this->update_array[$key];
} }
} }
@ -184,17 +212,47 @@ class BulkAssetsController extends Controller
$logAction->user_id = Auth::id(); $logAction->user_id = Auth::id();
$logAction->log_meta = json_encode($changed); $logAction->log_meta = json_encode($changed);
$logAction->logaction('update'); $logAction->logaction('update');
DB::table('assets') if($custom_fields_present) {
->where('id', $assetId) $asset = Asset::find($assetId);
->update($this->update_array); $assetCustomFields = $asset->model()->first()->fieldset;
} // endforeach if($assetCustomFields && $assetCustomFields->fields) {
foreach ($assetCustomFields->fields as $field) {
if (array_key_exists($field->db_column, $this->update_array)) {
$asset->{$field->db_column} = $this->update_array[$field->db_column];
$saved = $asset->save();
if(!$saved) {
$error_bag[] = $asset->getErrors();
}
continue;
} else {
$array = $this->update_array;
array_except($array, $field->db_column);
$asset->save($array);
}
if (!$asset->save()) {
$error_bag[] = $asset->getErrors();
}
}
}
} else {
Asset::find($assetId)->update($this->update_array);
}
}
if(!empty($error_bag)) {
$errors = [];
//find the customfield name from the name of the messagebag items
foreach ($error_bag as $key => $bag) {
foreach($bag->keys() as $key => $value) {
CustomField::where('db_column', $value)->get()->map(function($item) use (&$errors) {
$errors[] = $item->name;
});
}
}
return redirect($bulk_back_url)->with('bulk_errors', array_unique($errors));
}
return redirect($bulk_back_url)->with('success', trans('admin/hardware/message.update.success')); return redirect($bulk_back_url)->with('success', trans('admin/hardware/message.update.success'));
} }
// no values given, nothing to update // no values given, nothing to update
return redirect($bulk_back_url)->with('warning', trans('admin/hardware/message.update.nothing_updated')); return redirect($bulk_back_url)->with('warning', trans('admin/hardware/message.update.nothing_updated'));
} }

View file

@ -30,7 +30,7 @@ class LabelsController extends Controller
$exampleAsset = new Asset(); $exampleAsset = new Asset();
$exampleAsset->id = 999999; $exampleAsset->id = 999999;
$exampleAsset->name = 'AST-AB-CD-1234'; $exampleAsset->name = 'JEN-867-5309';
$exampleAsset->asset_tag = 'TCA-00001'; $exampleAsset->asset_tag = 'TCA-00001';
$exampleAsset->serial = 'SN9876543210'; $exampleAsset->serial = 'SN9876543210';

View file

@ -590,6 +590,7 @@ class SettingsController extends Controller
$setting->date_display_format = $request->input('date_display_format'); $setting->date_display_format = $request->input('date_display_format');
$setting->time_display_format = $request->input('time_display_format'); $setting->time_display_format = $request->input('time_display_format');
$setting->digit_separator = $request->input('digit_separator'); $setting->digit_separator = $request->input('digit_separator');
$setting->name_display_format = $request->input('name_display_format');
if ($setting->save()) { if ($setting->save()) {
return redirect()->route('settings.index') return redirect()->route('settings.index')

View file

@ -4,6 +4,10 @@ namespace App\Http\Transformers;
use App\Helpers\Helper; use App\Helpers\Helper;
use App\Models\Actionlog; use App\Models\Actionlog;
use App\Models\Setting; use App\Models\Setting;
use App\Models\Company;
use App\Models\Supplier;
use App\Models\Location;
use App\Models\AssetModel;
use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Eloquent\Collection;
class ActionlogsTransformer class ActionlogsTransformer
@ -46,13 +50,16 @@ class ActionlogsTransformer
if (($actionlog->log_meta) && ($actionlog->log_meta!='')) { if (($actionlog->log_meta) && ($actionlog->log_meta!='')) {
$meta_array = json_decode($actionlog->log_meta); $meta_array = json_decode($actionlog->log_meta);
$clean_meta = [];
if ($meta_array) { if ($meta_array) {
foreach ($meta_array as $fieldname => $fieldata) { foreach ($meta_array as $fieldname => $fieldata) {
$clean_meta[$fieldname]['old'] = $this->clean_field($fieldata->old); $clean_meta[$fieldname]['old'] = $this->clean_field($fieldata->old);
$clean_meta[$fieldname]['new'] = $this->clean_field($fieldata->new); $clean_meta[$fieldname]['new'] = $this->clean_field($fieldata->new);
} }
} }
$clean_meta= $this->changedInfo($clean_meta);
} }
$file_url = ''; $file_url = '';
@ -115,9 +122,7 @@ class ActionlogsTransformer
'log_meta' => ((isset($clean_meta)) && (is_array($clean_meta))) ? $clean_meta: null, 'log_meta' => ((isset($clean_meta)) && (is_array($clean_meta))) ? $clean_meta: null,
'action_date' => ($actionlog->action_date) ? Helper::getFormattedDateObject($actionlog->action_date, 'datetime'): Helper::getFormattedDateObject($actionlog->created_at, 'datetime'), 'action_date' => ($actionlog->action_date) ? Helper::getFormattedDateObject($actionlog->action_date, 'datetime'): Helper::getFormattedDateObject($actionlog->created_at, 'datetime'),
]; ];
//\Log::info("Clean Meta is: ".print_r($clean_meta,true));
//dd($array);
return $array; return $array;
} }
@ -132,7 +137,50 @@ class ActionlogsTransformer
} }
return (new DatatablesTransformer)->transformDatatables($array, $total); return (new DatatablesTransformer)->transformDatatables($array, $total);
} }
/**
* This takes the ids of the changed attributes and returns the names instead for the history view of an Asset
*
* @param array $clean_meta
* @return array
*/
public function changedInfo(array $clean_meta)
{
if(array_key_exists('rtd_location_id',$clean_meta)) {
$clean_meta['rtd_location_id']['old'] = $clean_meta['rtd_location_id']['old'] ? "[id: ".$clean_meta['rtd_location_id']['old']."] ". Location::find($clean_meta['rtd_location_id']['old'])->name : trans('general.unassigned');
$clean_meta['rtd_location_id']['new'] = $clean_meta['rtd_location_id']['new'] ? "[id: ".$clean_meta['rtd_location_id']['new']."] ". Location::find($clean_meta['rtd_location_id']['new'])->name : trans('general.unassigned');
$clean_meta['Default Location'] = $clean_meta['rtd_location_id'];
unset($clean_meta['rtd_location_id']);
}
if(array_key_exists('location_id', $clean_meta)) {
$clean_meta['location_id']['old'] = $clean_meta['location_id']['old'] ? "[id: ".$clean_meta['location_id']['old']."] ".Location::find($clean_meta['location_id']['old'])->name : trans('general.unassigned');
$clean_meta['location_id']['new'] = $clean_meta['location_id']['new'] ? "[id: ".$clean_meta['location_id']['new']."] ".Location::find($clean_meta['location_id']['new'])->name : trans('general.unassigned');
$clean_meta['Current Location'] = $clean_meta['location_id'];
unset($clean_meta['location_id']);
}
if(array_key_exists('model_id', $clean_meta)) {
$clean_meta['model_id']['old'] = "[id: ".$clean_meta['model_id']['old']."] ".AssetModel::withTrashed()->find($clean_meta['model_id']['old'])->name;
$clean_meta['model_id']['new'] = "[id: ".$clean_meta['model_id']['new']."] ".AssetModel::withTrashed()->find($clean_meta['model_id']['new'])->name; /* model is required at asset creation */
$clean_meta['Model'] = $clean_meta['model_id'];
unset($clean_meta['model_id']);
}
if(array_key_exists('company_id', $clean_meta)) {
$clean_meta['company_id']['old'] = $clean_meta['company_id']['old'] ? "[id: ".$clean_meta['company_id']['old']."]".Company::find($clean_meta['company_id']['old'])->name : trans('general.unassigned');
$clean_meta['company_id']['new'] = $clean_meta['company_id']['new'] ? "[id: ".$clean_meta['company_id']['new']."] ".Company::find($clean_meta['company_id']['new'])->name : trans('general.unassigned');
$clean_meta['Company'] = $clean_meta['company_id'];
unset($clean_meta['company_id']);
}
if(array_key_exists('supplier_id', $clean_meta)) {
$clean_meta['supplier_id']['old'] = $clean_meta['supplier_id']['old'] ? "[id: ".$clean_meta['supplier_id']['old']."] ".Supplier::find($clean_meta['supplier_id']['old'])->name : trans('general.unassigned');
$clean_meta['supplier_id']['new'] = $clean_meta['supplier_id']['new'] ? "[id: ".$clean_meta['supplier_id']['new']."] ".Supplier::find($clean_meta['supplier_id']['new'])->name : trans('general.unassigned');
$clean_meta['Supplier'] = $clean_meta['supplier_id'];
unset($clean_meta['supplier_id']);
}
return $clean_meta;
}
} }

View file

@ -26,8 +26,8 @@ class LabelsTransformer
'name' => $label->getName(), 'name' => $label->getName(),
'unit' => $label->getUnit(), 'unit' => $label->getUnit(),
'width' => $label->getWidth(), 'width' => number_format($label->getWidth(), 2),
'height' => $label->getHeight(), 'height' => number_format($label->getHeight(), 2),
'margin_top' => $label->getMarginTop(), 'margin_top' => $label->getMarginTop(),
'margin_bottom' => $label->getMarginBottom(), 'margin_bottom' => $label->getMarginBottom(),

View file

@ -24,7 +24,7 @@ class UsersTransformer
$array = [ $array = [
'id' => (int) $user->id, 'id' => (int) $user->id,
'avatar' => e($user->present()->gravatar), 'avatar' => e($user->present()->gravatar),
'name' => e($user->first_name).' '.e($user->last_name), 'name' => e($user->getFullNameAttribute()),
'first_name' => e($user->first_name), 'first_name' => e($user->first_name),
'last_name' => e($user->last_name), 'last_name' => e($user->last_name),
'username' => e($user->username), 'username' => e($user->username),

View file

@ -349,6 +349,22 @@ class Accessory extends SnipeModel
return (int) $remaining; return (int) $remaining;
} }
/**
* Run after the checkout acceptance was declined by the user
*
* @param User $acceptedBy
* @param string $signature
*/
public function declinedCheckout(User $declinedBy, $signature)
{
if (is_null($accessory_user = \DB::table('accessories_users')->where('assigned_to', $declinedBy->id)->where('accessory_id', $this->id)->latest('created_at'))) {
// Redirect to the accessory management page with error
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.does_not_exist'));
}
$accessory_user->limit(1)->delete();
}
/** /**
* Query builder scope to order on company * Query builder scope to order on company
* *

View file

@ -1433,6 +1433,12 @@ class Asset extends Depreciable
}); });
} }
if ($fieldname == 'rtd_location') {
$query->whereHas('defaultLoc', function ($query) use ($search_val) {
$query->where('locations.name', 'LIKE', '%'.$search_val.'%');
});
}
if ($fieldname =='assigned_to') { if ($fieldname =='assigned_to') {
$query->whereHasMorph('assignedTo', [User::class], function ($query) use ($search_val) { $query->whereHasMorph('assignedTo', [User::class], function ($query) use ($search_val) {
$query->where(function ($query) use ($search_val) { $query->where(function ($query) use ($search_val) {

View file

@ -150,6 +150,11 @@ class AssetModel extends SnipeModel
{ {
return $this->belongsTo(\App\Models\CustomFieldset::class, 'fieldset_id'); return $this->belongsTo(\App\Models\CustomFieldset::class, 'fieldset_id');
} }
public function customFields()
{
return $this->fieldset()->first()->fields();
}
/** /**
* Establishes the model -> custom field default values relationship * Establishes the model -> custom field default values relationship

View file

@ -9,7 +9,6 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Validation\Rule; use Illuminate\Validation\Rule;
use Schema; use Schema;
use Watson\Validating\ValidatingTrait; use Watson\Validating\ValidatingTrait;
class CustomField extends Model class CustomField extends Model
{ {
use HasFactory; use HasFactory;
@ -182,6 +181,11 @@ class CustomField extends Model
{ {
return $this->belongsToMany(\App\Models\CustomFieldset::class); return $this->belongsToMany(\App\Models\CustomFieldset::class);
} }
public function assetModels()
{
return $this->fieldset()->with('models')->get()->pluck('models')->flatten()->unique('id');
}
/** /**
* Establishes the customfield -> admin user relationship * Establishes the customfield -> admin user relationship

View file

@ -37,7 +37,7 @@ class DefaultLabel extends RectangleSheet
private int $columns; private int $columns;
private int $rows; private int $rows;
public function __construct() { public function __construct() {
$settings = Setting::getSettings(); $settings = Setting::getSettings();
@ -62,6 +62,16 @@ class DefaultLabel extends RectangleSheet
$this->columns = ($usableWidth + $this->labelSpacingH) / ($this->labelWidth + $this->labelSpacingH); $this->columns = ($usableWidth + $this->labelSpacingH) / ($this->labelWidth + $this->labelSpacingH);
$this->rows = ($usableHeight + $this->labelSpacingV) / ($this->labelHeight + $this->labelSpacingV); $this->rows = ($usableHeight + $this->labelSpacingV) / ($this->labelHeight + $this->labelSpacingV);
// Make sure the columns and rows are never zero, since that scenario should never happen
if ($this->columns == 0) {
$this->columns = 1;
}
if ($this->rows == 0) {
$this->rows = 1;
}
} }
public function getUnit() { return 'in'; } public function getUnit() { return 'in'; }
@ -76,7 +86,7 @@ class DefaultLabel extends RectangleSheet
public function getColumns() { return $this->columns; } public function getColumns() { return $this->columns; }
public function getRows() { return $this->rows; } public function getRows() { return $this->rows; }
public function getLabelBorder() { return 0.01; } public function getLabelBorder() { return 0; }
public function getLabelWidth() { return $this->labelWidth; } public function getLabelWidth() { return $this->labelWidth; }
public function getLabelHeight() { return $this->labelHeight; } public function getLabelHeight() { return $this->labelHeight; }
@ -85,7 +95,7 @@ class DefaultLabel extends RectangleSheet
public function getLabelMarginBottom() { return 0; } public function getLabelMarginBottom() { return 0; }
public function getLabelMarginLeft() { return 0; } public function getLabelMarginLeft() { return 0; }
public function getLabelMarginRight() { return 0; } public function getLabelMarginRight() { return 0; }
public function getLabelColumnSpacing() { return $this->labelSpacingH; } public function getLabelColumnSpacing() { return $this->labelSpacingH; }
public function getLabelRowSpacing() { return $this->labelSpacingV; } public function getLabelRowSpacing() { return $this->labelSpacingV; }
@ -106,7 +116,7 @@ class DefaultLabel extends RectangleSheet
$textY = 0; $textY = 0;
$textX1 = 0; $textX1 = 0;
$textX2 = $this->getLabelWidth(); $textX2 = $this->getLabelWidth();
// 1D Barcode // 1D Barcode
if ($record->get('barcode1d')) { if ($record->get('barcode1d')) {
static::write1DBarcode( static::write1DBarcode(
@ -115,7 +125,7 @@ class DefaultLabel extends RectangleSheet
$this->getLabelWidth() - 0.1, self::BARCODE1D_SIZE $this->getLabelWidth() - 0.1, self::BARCODE1D_SIZE
); );
} }
// 2D Barcode // 2D Barcode
if ($record->get('barcode2d')) { if ($record->get('barcode2d')) {
static::write2DBarcode( static::write2DBarcode(

View file

@ -370,7 +370,11 @@ abstract class Label
*/ */
public final function write1DBarcode(TCPDF $pdf, $value, $type, $x, $y, $width, $height) { public final function write1DBarcode(TCPDF $pdf, $value, $type, $x, $y, $width, $height) {
if (empty($value)) return; if (empty($value)) return;
$pdf->write1DBarcode($value, $type, $x, $y, $width, $height, null, ['stretch'=>true]); try {
$pdf->write1DBarcode($value, $type, $x, $y, $width, $height, null, ['stretch'=>true]);
} catch (\Exception $e) {
\Log::error('The 1D barcode ' . $value . ' is not compliant with the barcode type '. $type);
}
} }
/** /**

View file

@ -0,0 +1,19 @@
<?php
namespace App\Models\Labels\Tapes\Dymo;
use App\Helpers\Helper;
use App\Models\Labels\Label;
abstract class LabelWriter extends Label
{
private const HEIGHT = 1.15;
private const MARGIN_SIDES = 0.1;
private const MARGIN_ENDS = 0.1;
public function getHeight() { return Helper::convertUnit(self::HEIGHT, 'in', $this->getUnit()); }
public function getMarginTop() { return Helper::convertUnit(self::MARGIN_SIDES, 'in', $this->getUnit()); }
public function getMarginBottom() { return Helper::convertUnit(self::MARGIN_SIDES, 'in', $this->getUnit());}
public function getMarginLeft() { return Helper::convertUnit(self::MARGIN_ENDS, 'in', $this->getUnit()); }
public function getMarginRight() { return Helper::convertUnit(self::MARGIN_ENDS, 'in', $this->getUnit()); }
}

View file

@ -0,0 +1,90 @@
<?php
namespace App\Models\Labels\Tapes\Dymo;
class LabelWriter_30252 extends LabelWriter
{
private const BARCODE_MARGIN = 1.80;
private const TAG_SIZE = 2.80;
private const TITLE_SIZE = 2.80;
private const TITLE_MARGIN = 0.50;
private const LABEL_SIZE = 2.00;
private const LABEL_MARGIN = - 0.35;
private const FIELD_SIZE = 3.20;
private const FIELD_MARGIN = 0.15;
public function getUnit() { return 'mm'; }
public function getWidth() { return 96.52; }
public function getSupportAssetTag() { return true; }
public function getSupport1DBarcode() { return true; }
public function getSupport2DBarcode() { return true; }
public function getSupportFields() { return 3; }
public function getSupportLogo() { return false; }
public function getSupportTitle() { return true; }
public function preparePDF($pdf) {}
public function write($pdf, $record) {
$pa = $this->getPrintableArea();
$currentX = $pa->x1;
$currentY = $pa->y1;
$usableWidth = $pa->w;
$barcodeSize = $pa->h - self::TAG_SIZE;
if ($record->has('barcode2d')) {
static::writeText(
$pdf, $record->get('tag'),
$pa->x1, $pa->y2 - self::TAG_SIZE,
'freemono', 'b', self::TAG_SIZE, 'C',
$barcodeSize, self::TAG_SIZE, true, 0
);
static::write2DBarcode(
$pdf, $record->get('barcode2d')->content, $record->get('barcode2d')->type,
$currentX, $currentY,
$barcodeSize, $barcodeSize
);
$currentX += $barcodeSize + self::BARCODE_MARGIN;
$usableWidth -= $barcodeSize + self::BARCODE_MARGIN;
} else {
static::writeText(
$pdf, $record->get('tag'),
$pa->x1, $pa->y2 - self::TAG_SIZE,
'freemono', 'b', self::TAG_SIZE, 'R',
$usableWidth, self::TAG_SIZE, true, 0
);
}
if ($record->has('title')) {
static::writeText(
$pdf, $record->get('title'),
$currentX, $currentY,
'freesans', '', self::TITLE_SIZE, 'L',
$usableWidth, self::TITLE_SIZE, true, 0
);
$currentY += self::TITLE_SIZE + self::TITLE_MARGIN;
}
foreach ($record->get('fields') as $field) {
static::writeText(
$pdf, $field['label'],
$currentX, $currentY,
'freesans', '', self::LABEL_SIZE, 'L',
$usableWidth, self::LABEL_SIZE, true, 0, 0
);
$currentY += self::LABEL_SIZE + self::LABEL_MARGIN;
static::writeText(
$pdf, $field['value'],
$currentX, $currentY,
'freemono', 'B', self::FIELD_SIZE, 'L',
$usableWidth, self::FIELD_SIZE, true, 0, 0.3
);
$currentY += self::FIELD_SIZE + self::FIELD_MARGIN;
}
}
}

View file

@ -247,21 +247,12 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
*/ */
public function getFullNameAttribute() public function getFullNameAttribute()
{ {
return $this->first_name.' '.$this->last_name; $setting = Setting::getSettings();
}
/** if ($setting->name_display_format=='last_first') {
* Returns the complete name attribute with username return ($this->last_name) ? $this->last_name.' '.$this->first_name : $this->first_name;
* }
* @todo refactor this so it's less repetitive and dumb return $this->last_name ? $this->first_name.' '.$this->last_name : $this->first_name;
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v2.0]
* @return string
*/
public function getCompleteNameAttribute()
{
return $this->last_name.', '.$this->first_name.' ('.$this->username.')';
} }

View file

@ -74,9 +74,9 @@ class AssetObserver
$tag = $asset->asset_tag; $tag = $asset->asset_tag;
$prefix = $settings->auto_increment_prefix; $prefix = $settings->auto_increment_prefix;
$number = substr($tag, strlen($prefix)); $number = substr($tag, strlen($prefix));
// IF - auto_increment_assets is on, AND (the prefix matches the start of the tag OR there is no prefix) // IF - auto_increment_assets is on, AND (there is no prefix OR the prefix matches the start of the tag)
// AND the rest of the string after the prefix is all digits, THEN... // AND the rest of the string after the prefix is all digits, THEN...
if ($settings->auto_increment_assets && (strpos($tag, $prefix) === 0 || $prefix=='') && preg_match('/\d+/',$number) === 1) { if ($settings->auto_increment_assets && ($prefix=='' || strpos($tag, $prefix) === 0) && preg_match('/\d+/',$number) === 1) {
// new way of auto-trueing-up auto_increment ID's // new way of auto-trueing-up auto_increment ID's
$next_asset_tag = intval($number, 10) + 1; $next_asset_tag = intval($number, 10) + 1;
// we had to use 'intval' because the $number could be '01234' and // we had to use 'intval' because the $number could be '01234' and

View file

@ -21,7 +21,7 @@ class LabelPresenter extends Presenter
], [ ], [
'field' => 'name', 'field' => 'name',
'searchable' => true, 'searchable' => true,
'sortable' => true, 'sortable' => false,
'switchable' => true, 'switchable' => true,
'title' => trans('general.name'), 'title' => trans('general.name'),
'visible' => true, 'visible' => true,
@ -44,14 +44,14 @@ class LabelPresenter extends Presenter
], [ ], [
'field' => 'support_fields', 'field' => 'support_fields',
'searchable' => false, 'searchable' => false,
'sortable' => true, 'sortable' => false,
'switchable' => true, 'switchable' => true,
'title' => trans('admin/labels/table.support_fields'), 'title' => trans('admin/labels/table.support_fields'),
'visible' => true 'visible' => true
], [ ], [
'field' => 'support_asset_tag', 'field' => 'support_asset_tag',
'searchable' => false, 'searchable' => false,
'sortable' => true, 'sortable' => false,
'switchable' => true, 'switchable' => true,
'title' => trans('admin/labels/table.support_asset_tag'), 'title' => trans('admin/labels/table.support_asset_tag'),
'visible' => true, 'visible' => true,
@ -59,7 +59,7 @@ class LabelPresenter extends Presenter
], [ ], [
'field' => 'support_1d_barcode', 'field' => 'support_1d_barcode',
'searchable' => false, 'searchable' => false,
'sortable' => true, 'sortable' => false,
'switchable' => true, 'switchable' => true,
'title' => trans('admin/labels/table.support_1d_barcode'), 'title' => trans('admin/labels/table.support_1d_barcode'),
'visible' => true, 'visible' => true,
@ -67,7 +67,7 @@ class LabelPresenter extends Presenter
], [ ], [
'field' => 'support_2d_barcode', 'field' => 'support_2d_barcode',
'searchable' => false, 'searchable' => false,
'sortable' => true, 'sortable' => false,
'switchable' => true, 'switchable' => true,
'title' => trans('admin/labels/table.support_2d_barcode'), 'title' => trans('admin/labels/table.support_2d_barcode'),
'visible' => true, 'visible' => true,
@ -75,7 +75,7 @@ class LabelPresenter extends Presenter
], [ ], [
'field' => 'support_logo', 'field' => 'support_logo',
'searchable' => false, 'searchable' => false,
'sortable' => true, 'sortable' => false,
'switchable' => true, 'switchable' => true,
'title' => trans('admin/labels/table.support_logo'), 'title' => trans('admin/labels/table.support_logo'),
'visible' => true, 'visible' => true,
@ -83,7 +83,7 @@ class LabelPresenter extends Presenter
], [ ], [
'field' => 'support_title', 'field' => 'support_title',
'searchable' => false, 'searchable' => false,
'sortable' => true, 'sortable' => false,
'switchable' => true, 'switchable' => true,
'title' => trans('admin/labels/table.support_title'), 'title' => trans('admin/labels/table.support_title'),
'visible' => true, 'visible' => true,

View file

@ -433,7 +433,7 @@ class UserPresenter extends Presenter
*/ */
public function nameUrl() public function nameUrl()
{ {
return (string) link_to_route('users.show', $this->fullName(), $this->id); return (string) link_to_route('users.show', $this->getFullNameAttribute(), $this->id);
} }
/** /**

View file

@ -39,7 +39,7 @@ class Label implements View
$assets = $this->data->get('assets'); $assets = $this->data->get('assets');
$offset = $this->data->get('offset'); $offset = $this->data->get('offset');
$template = $this->data->get('template'); $template = $this->data->get('template');
// If disabled, pass to legacy view // If disabled, pass to legacy view
if ((!$settings->label2_enable) && (!$template)) { if ((!$settings->label2_enable) && (!$template)) {
return view('hardware/labels') return view('hardware/labels')
@ -49,8 +49,12 @@ class Label implements View
->with('count', $this->data->get('count')); ->with('count', $this->data->get('count'));
} }
if (empty($template)) $template = LabelModel::find($settings->label2_template); // If a specific template was set, use it, otherwise fall back to default
elseif (is_string($template)) $template = LabelModel::find($template); if (empty($template)) {
$template = LabelModel::find($settings->label2_template);
} elseif (is_string($template)) {
$template = LabelModel::find($template);
}
$template->validate(); $template->validate();
@ -87,25 +91,36 @@ class Label implements View
$assetData->put('tag', $asset->asset_tag); $assetData->put('tag', $asset->asset_tag);
if ($template->getSupportTitle()) { if ($template->getSupportTitle()) {
$title = !empty($settings->label2_title) ?
str_ireplace('{COMPANY}', $asset->company->name, $settings->label2_title) : if ($asset->company && !empty($settings->label2_title)) {
$title = str_replace('{COMPANY}', $asset->company->name, $settings->label2_title);
$settings->qr_text; $settings->qr_text;
if (!empty($title)) $assetData->put('title', $title); $assetData->put('title', $title);
}
} }
if ($template->getSupportLogo()) { if ($template->getSupportLogo()) {
$logo = $settings->label2_asset_logo ?
( $logo = null;
!empty($asset->company->image) ?
Storage::disk('public')->path('companies/'.e($asset->company->image)) : // Should we be trying to use a logo at all?
null if ($settings->label2_asset_logo='1') {
) :
( // If we don't have a company image, fall back to the general site label image
!empty($settings->label_logo) ? if (!empty($settings->label_logo)) {
Storage::disk('public')->path(''.e($settings->label_logo)) : $logo = Storage::disk('public')->path('/'.e($settings->label_logo));
null }
);
if (!empty($logo)) $assetData->put('logo', $logo); // If we have a company logo, use that first
if (($asset->company) && ($asset->company->image!='')) {
$logo = Storage::disk('public')->path('companies/'.e($asset->company->image));
}
}
if (!empty($logo)) {
$assetData->put('logo', $logo);
}
} }
if ($template->getSupport1DBarcode()) { if ($template->getSupport1DBarcode()) {

643
composer.lock generated

File diff suppressed because it is too large Load diff

View file

@ -21,11 +21,7 @@ class AddLabel2Settings extends Migration
$table->string('label2_1d_type')->default('default'); $table->string('label2_1d_type')->default('default');
$table->string('label2_2d_type')->default('default'); $table->string('label2_2d_type')->default('default');
$table->string('label2_2d_target')->default('hardware_id'); $table->string('label2_2d_target')->default('hardware_id');
$table->string('label2_fields')->default( $table->string('label2_fields')->default('name=name;serial=serial;model=model.name;');
trans('admin/hardware/form.name').'=name;'.
trans('admin/hardware/form.serial').'=serial;'.
trans('admin/hardware/form.model').'=model.name;'
);
}); });
} }

View file

@ -0,0 +1,32 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddNameOrderingToSettings extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('settings', function (Blueprint $table) {
$table->string('name_display_format', 10)->after('alert_threshold')->nullable()->default('first_last');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('settings', function (Blueprint $table) {
$table->dropColumn('name_display_format');
});
}
}

View file

@ -10,6 +10,9 @@ return [
'bulk_update' => 'Bulk Update Assets', 'bulk_update' => 'Bulk Update Assets',
'bulk_update_help' => 'This form allows you to update multiple assets at once. Only fill in the fields you need to change. Any fields left blank will remain unchanged. ', 'bulk_update_help' => 'This form allows you to update multiple assets at once. Only fill in the fields you need to change. Any fields left blank will remain unchanged. ',
'bulk_update_warn' => 'You are about to edit the properties of a single asset.|You are about to edit the properties of :asset_count assets.', 'bulk_update_warn' => 'You are about to edit the properties of a single asset.|You are about to edit the properties of :asset_count assets.',
'bulk_update_with_custom_field' => 'Note the assets are :asset_model_count different types of models.',
'bulk_update_model_prefix' => 'On Models',
'bulk_update_custom_field_unique' => 'This is a unique field and can not be bulk edited.',
'checkedout_to' => 'Checked Out To', 'checkedout_to' => 'Checked Out To',
'checkout_date' => 'Checkout Date', 'checkout_date' => 'Checkout Date',
'checkin_date' => 'Checkin Date', 'checkin_date' => 'Checkin Date',

View file

@ -349,7 +349,7 @@ return [
'label2_fields_help' => 'Fields can be added, removed, and reordered in the left column. For each field, multiple options for Label and DataSource can be added, removed, and reordered in the right column.', 'label2_fields_help' => 'Fields can be added, removed, and reordered in the left column. For each field, multiple options for Label and DataSource can be added, removed, and reordered in the right column.',
'help_asterisk_bold' => 'Text entered as <code>**text**</code> will be displayed as bold', 'help_asterisk_bold' => 'Text entered as <code>**text**</code> will be displayed as bold',
'help_blank_to_use' => 'Leave blank to use the value from <code>:setting_name</code>', 'help_blank_to_use' => 'Leave blank to use the value from <code>:setting_name</code>',
'help_default_will_use' => '<code>:default</code> will use the value from <code>:setting_name</code>', 'help_default_will_use' => '<code>:default</code> will use the value from <code>:setting_name</code>. <br>Note that the value of the barcodes must comply with the respective barcode spec in order to be successfully generated. Please see <a href="https://snipe-it.readme.io/docs/barcodes">the documentation <i class="fa fa-external-link"></i></a> for more details. ',
'default' => 'Default', 'default' => 'Default',
'none' => 'None', 'none' => 'None',
'google_callback_help' => 'This should be entered as the callback URL in your Google OAuth app settings in your organization&apos;s <strong><a href="https://console.cloud.google.com/" target="_blank">Google developer console <i class="fa fa-external-link" aria-hidden="true"></i></a></strong>.', 'google_callback_help' => 'This should be entered as the callback URL in your Google OAuth app settings in your organization&apos;s <strong><a href="https://console.cloud.google.com/" target="_blank">Google developer console <i class="fa fa-external-link" aria-hidden="true"></i></a></strong>.',

View file

@ -120,6 +120,9 @@ return [
'firstname_lastname_underscore_format' => 'First Name Last Name (jane_smith@example.com)', 'firstname_lastname_underscore_format' => 'First Name Last Name (jane_smith@example.com)',
'lastnamefirstinitial_format' => 'Last Name First Initial (smithj@example.com)', 'lastnamefirstinitial_format' => 'Last Name First Initial (smithj@example.com)',
'firstintial_dot_lastname_format' => 'First Initial Last Name (j.smith@example.com)', 'firstintial_dot_lastname_format' => 'First Initial Last Name (j.smith@example.com)',
'firstname_lastname_display' => 'First Name Last Name (Jane Smith)',
'lastname_firstname_display' => 'Last Name First Name (Smith Jane)',
'name_display_format' => 'Name Display Format',
'first' => 'First', 'first' => 'First',
'firstnamelastname' => 'First Name Last Name (janesmith@example.com)', 'firstnamelastname' => 'First Name Last Name (janesmith@example.com)',
'lastname_firstinitial' => 'Last Name First Initial (smith_j@example.com)', 'lastname_firstinitial' => 'Last Name First Initial (smith_j@example.com)',
@ -283,6 +286,7 @@ return [
'user' => 'User', 'user' => 'User',
'accepted' => 'accepted', 'accepted' => 'accepted',
'declined' => 'declined', 'declined' => 'declined',
'unassigned' => 'Unassigned',
'unaccepted_asset_report' => 'Unaccepted Assets', 'unaccepted_asset_report' => 'Unaccepted Assets',
'users' => 'Users', 'users' => 'Users',
'viewall' => 'View All', 'viewall' => 'View All',
@ -364,6 +368,7 @@ return [
'licenses_count' => 'Licenses Count', 'licenses_count' => 'Licenses Count',
'notification_error' => 'Error:', 'notification_error' => 'Error:',
'notification_error_hint' => 'Please check the form below for errors', 'notification_error_hint' => 'Please check the form below for errors',
'notification_bulk_error_hint' => 'The following fields had validation errors and were not edited:',
'notification_success' => 'Success:', 'notification_success' => 'Success:',
'notification_warning' => 'Warning:', 'notification_warning' => 'Warning:',
'notification_info' => 'Info:', 'notification_info' => 'Info:',
@ -452,6 +457,8 @@ return [
'serial_number' => 'Serial Number', 'serial_number' => 'Serial Number',
'item_notes' => ':item Notes', 'item_notes' => ':item Notes',
'item_name_var' => ':item Name', 'item_name_var' => ':item Name',
'error_user_company' => 'User and Asset companies missmatch',
'error_user_company_accept_view' => 'An Asset assigned to you belongs to a different company so you can\'t accept nor deny it, please check with your manager',
'importer' => [ 'importer' => [
'checked_out_to_fullname' => 'Checked Out to: Full Name', 'checked_out_to_fullname' => 'Checked Out to: Full Name',
'checked_out_to_first_name' => 'Checked Out to: First Name', 'checked_out_to_first_name' => 'Checked Out to: First Name',

View file

@ -11,7 +11,7 @@ Form::macro('locales', function ($name = 'locale', $selected = null, $class = nu
$idclause = (!is_null($id)) ? $id : ''; $idclause = (!is_null($id)) ? $id : '';
$select = '<select name="'.$name.'" class="'.$class.'" style="min-width:350px"'.$idclause.' aria-label="'.$name.'" data-placeholder="'.trans('localizations.select_language').'">'; $select = '<select name="'.$name.'" class="'.$class.'" style="min-width:100%"'.$idclause.' aria-label="'.$name.'" data-placeholder="'.trans('localizations.select_language').'">';
$select .= '<option value="" role="option">'.trans('localizations.select_language').'</option>'; $select .= '<option value="" role="option">'.trans('localizations.select_language').'</option>';
// Pull the autoglossonym array from the localizations translation file // Pull the autoglossonym array from the localizations translation file
@ -109,6 +109,23 @@ Form::macro('digit_separator', function ($name = 'digit_separator', $selected =
return $select; return $select;
}); });
Form::macro('name_display_format', function ($name = 'name_display_format', $selected = null, $class = null) {
$formats = [
'first_last' => trans('general.firstname_lastname_display'),
'last_first' => trans('general.lastname_firstname_display'),
];
$select = '<select name="'.$name.'" class="'.$class.'" style="width: 100%" aria-label="'.$name.'">';
foreach ($formats as $format => $label) {
$select .= '<option value="'.$format.'"'.($selected == $format ? ' selected="selected" role="option" aria-selected="true"' : ' aria-selected="false"').'>'.$label.'</option> '."\n";
}
$select .= '</select>';
return $select;
});
/** /**
* Barcode macro * Barcode macro
* Generates the dropdown menu of available 1D barcodes * Generates the dropdown menu of available 1D barcodes

View file

@ -41,8 +41,13 @@
<tbody> <tbody>
@foreach ($acceptances as $acceptance) @foreach ($acceptances as $acceptance)
<tr> <tr>
@if ($acceptance->checkoutable)
<td>{{ ($acceptance->checkoutable) ? $acceptance->checkoutable->present()->name : '' }}</td> <td>{{ ($acceptance->checkoutable) ? $acceptance->checkoutable->present()->name : '' }}</td>
<td><a href="{{ route('account.accept.item', $acceptance) }}" class="btn btn-default btn-sm">{{ trans('general.accept_decline') }}</a></td> <td><a href="{{ route('account.accept.item', $acceptance) }}" class="btn btn-default btn-sm">{{ trans('general.accept_decline') }}</a></td>
@else
<td> ----- </td>
<td> {{ trans('general.error_user_company_accept_view') }} </td>
@endif
</tr> </tr>
@endforeach @endforeach
</tbody> </tbody>

View file

@ -46,7 +46,7 @@
<!-- Language --> <!-- Language -->
<div class="form-group {{ $errors->has('locale') ? 'has-error' : '' }}"> <div class="form-group {{ $errors->has('locale') ? 'has-error' : '' }}">
<label class="col-md-3 control-label" for="locale">{{ trans('general.language') }}</label> <label class="col-md-3 control-label" for="locale">{{ trans('general.language') }}</label>
<div class="col-md-9"> <div class="col-md-7">
@if (!config('app.lock_passwords')) @if (!config('app.lock_passwords'))
{!! Form::locales('locale', old('locale', $user->locale), 'select2') !!} {!! Form::locales('locale', old('locale', $user->locale), 'select2') !!}

View file

@ -2,7 +2,7 @@
{{-- Page title --}} {{-- Page title --}}
@section('title') @section('title')
{{ trans('general.hello_name', array('name' => $user->present()->fullName())) }} {{ trans('general.hello_name', array('name' => $user->present()->getFullNameAttribute())) }}
@parent @parent
@stop @stop

View file

@ -21,6 +21,9 @@
<div class="callout callout-warning"> <div class="callout callout-warning">
<i class="fas fa-exclamation-triangle"></i> {{ trans_choice('admin/hardware/form.bulk_update_warn', count($assets), ['asset_count' => count($assets)]) }} <i class="fas fa-exclamation-triangle"></i> {{ trans_choice('admin/hardware/form.bulk_update_warn', count($assets), ['asset_count' => count($assets)]) }}
@if (count($models) > 0)
{{ trans_choice('admin/hardware/form.bulk_update_with_custom_field', count($models), ['asset_model_count' => count($models)]) }}
@endif
</div> </div>
<form class="form-horizontal" method="post" action="{{ route('hardware/bulksave') }}" autocomplete="off" role="form"> <form class="form-horizontal" method="post" action="{{ route('hardware/bulksave') }}" autocomplete="off" role="form">
@ -182,6 +185,8 @@
</div> </div>
</div> </div>
@include("models/custom_fields_form_bulk_edit",["models" => $models])
@foreach ($assets as $key => $value) @foreach ($assets as $key => $value)
<input type="hidden" name="ids[{{ $value }}]" value="1"> <input type="hidden" name="ids[{{ $value }}]" value="1">
@endforeach @endforeach

View file

@ -328,7 +328,7 @@
<i class="fas fa-users" aria-hidden="true"></i> <i class="fas fa-users" aria-hidden="true"></i>
@endif @endif
<span class="hidden-xs">{{ Auth::user()->first_name }} <strong <span class="hidden-xs">{{ Auth::user()->getFullNameAttribute() }} <strong
class="caret"></strong></span> class="caret"></strong></span>
</a> </a>
<ul class="dropdown-menu"> <ul class="dropdown-menu">

View file

@ -0,0 +1,119 @@
@php
//set array up before loop so it doesn't get wiped at every iteration
$fields = [];
@endphp
@foreach($models as $model)
@if (($model) && ($model->fieldset))
@foreach($model->fieldset->fields AS $field)
@php
//prevents some duplicate queries - open to a better way of skipping dupes in output
//its ugly, but if we'd rather deal with duplicate queries we can get rid of this.
if (in_array($field->db_column_name(), $fields)) {
$duplicate = true;
continue;
} else {
$duplicate = false;
}
$fields[] = $field->db_column_name();
@endphp
<div class="form-group{{ $errors->has($field->db_column_name()) ? ' has-error' : '' }}">
<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(),
Request::old($field->db_column_name(),(isset($item) ? Helper::gracefulDecrypt($field, htmlspecialchars($item->{$field->db_column_name()}, ENT_QUOTES)) : $field->defaultValue($model->id))), ['class'=>'format select2 form-control']) }}
@elseif ($field->element=='textarea')
@if($field->is_unique)
<input type="text" class="form-control" disabled value="{{ trans('/admin/hardware/form.bulk_update_custom_field_unique') }}">
@endif
@if(!$field->is_unique)
<textarea class="col-md-6 form-control" id="{{ $field->db_column_name() }}" name="{{ $field->db_column_name() }}">{{ Request::old($field->db_column_name(),(isset($item) ? Helper::gracefulDecrypt($field, $item->{$field->db_column_name()}) : $field->defaultValue($model->id))) }}</textarea>
@endif
@elseif ($field->element=='checkbox')
<!-- Checkboxes -->
@foreach ($field->formatFieldValuesAsArray() as $key => $value)
<div>
<label>
<input type="checkbox" value="{{ $value }}" name="{{ $field->db_column_name() }}[]" class="minimal" {{ isset($item) ? (in_array($value, array_map('trim', explode(',', $item->{$field->db_column_name()}))) ? ' checked="checked"' : '') : (Request::old($field->db_column_name()) != '' ? ' checked="checked"' : (in_array($key, array_map('trim', explode(',', $field->defaultValue($model->id)))) ? ' checked="checked"' : '')) }}>
{{ $value }}
</label>
</div>
@endforeach
@elseif ($field->element=='radio')
@foreach ($field->formatFieldValuesAsArray() as $value)
<div>
<label>
<input type="radio" value="{{ $value }}" name="{{ $field->db_column_name() }}" class="minimal" {{ isset($item) ? ($item->{$field->db_column_name()} == $value ? ' checked="checked"' : '') : (Request::old($field->db_column_name()) != '' ? ' checked="checked"' : (in_array($value, explode(', ', $field->defaultValue($model->id))) ? ' checked="checked"' : '')) }}>
{{ $value }}
</label>
</div>
@endforeach
@endif
@else
<!-- Date field -->
@if ($field->format=='DATE')
<div class="input-group col-md-5" style="padding-left: 0px;">
<div class="input-group date" data-provide="datepicker" data-date-format="yyyy-mm-dd" data-autoclose="true" data-date-clear-btn="true">
<input type="text" class="form-control" placeholder="{{ trans('general.select_date') }}" name="{{ $field->db_column_name() }}" id="{{ $field->db_column_name() }}" readonly value="{{ old($field->db_column_name(),(isset($item) ? Helper::gracefulDecrypt($field, $item->{$field->db_column_name()}) : $field->defaultValue($model->id))) }}" style="background-color:inherit">
<span class="input-group-addon"><i class="fas fa-calendar" aria-hidden="true"></i></span>
</div>
</div>
@else
@if (($field->field_encrypted=='0') || (Gate::allows('admin')))
@if ($field->is_unique)
<input type="text" class="form-control" disabled value="{{trans('/admin/hardware/form.bulk_update_custom_field_unique')}}">
@endif
@if(!$field->is_unique)
<input type="text" value="{{ Request::old($field->db_column_name(),(isset($item) ? Helper::gracefulDecrypt($field, $item->{$field->db_column_name()}) : $field->defaultValue($model->id))) }}" id="{{ $field->db_column_name() }}" class="form-control" name="{{ $field->db_column_name() }}" placeholder="Enter {{ strtolower($field->format) }} text">
@endif
@else
<input type="text" value="{{ strtoupper(trans('admin/custom_fields/general.encrypted')) }}" class="form-control disabled" disabled>
@endif
@endif
@endif
@if ($field->help_text!='')
<p class="help-block">{{ $field->help_text }}</p>
@endif
<p>{{ trans('admin/hardware/form.bulk_update_model_prefix') }}:
{{$field->assetModels()->pluck('name')->intersect($modelNames)->implode(', ')}}
</p>
<?php
$errormessage=$errors->first($field->db_column_name());
if ($errormessage) {
$errormessage=preg_replace('/ snipeit /', '', $errormessage);
print('<span class="alert-msg" aria-hidden="true"><i class="fas fa-times" aria-hidden="true"></i> '.$errormessage.'</span>');
}
?>
</div>
@if ($field->field_encrypted)
<div class="col-md-1 col-sm-1 text-left">
<i class="fas fa-lock" data-toggle="tooltip" data-placement="top" title="{{ trans('admin/custom_fields/general.value_encrypted') }}"></i>
</div>
@endif
</div>
@endforeach
@endif
@endforeach

View file

@ -115,6 +115,23 @@
@endif @endif
@if ($messages = Session::get('bulk_errors'))
<div class="col-md-12">
<div class="alert alert alert-danger fade in">
<button type="button" class="close" data-dismiss="alert">&times;</button>
<i class="fas fa-exclamation-triangle faa-pulse animated"></i>
<strong>{{ trans('general.notification_error') }} </strong>
{{ trans('general.notification_bulk_error_hint') }}
@foreach($messages as $message)
<ul>
<li>{{ $message }}</li>
</ul>
@endforeach
</div>
</div>
@endif
@if ($message = Session::get('warning')) @if ($message = Session::get('warning'))
<div class="col-md-12"> <div class="col-md-12">
<div class="alert alert-warning fade in"> <div class="alert alert-warning fade in">

View file

@ -14,11 +14,7 @@
{{-- Page content --}} {{-- Page content --}}
@section('content') @section('content')
<style>
.checkbox label {
padding-right: 40px;
}
</style>
@ -260,11 +256,13 @@
trans('admin/settings/general.show_archived_in_list')) }} trans('admin/settings/general.show_archived_in_list')) }}
</div> </div>
<div class="col-md-9"> <div class="col-md-9">
{{ Form::checkbox('show_archived_in_list', '1', Request::old('show_archived_in_list', $setting->show_archived_in_list),array('class' => 'minimal')) }}
{{ trans('admin/settings/general.show_archived_in_list_text') }}
{!! $errors->first('show_archived_in_list', '<span class="alert-msg" aria-hidden="true">:message</span>') !!}
</div> <label class="form-control">
{{ Form::checkbox('show_archived_in_list', '1', old('show_archived_in_list', $setting->show_archived_in_list),array('aria-label'=>'show_archived_in_list')) }}
{{ trans('admin/settings/general.show_archived_in_list_text') }}
</label>
{!! $errors->first('show_archived_in_list', '<span class="alert-msg" aria-hidden="true">:message</span>') !!}
</div>
</div> </div>
<!-- Show assets assigned to user's assets --> <!-- Show assets assigned to user's assets -->
@ -274,8 +272,10 @@
trans('admin/settings/general.show_assigned_assets')) }} trans('admin/settings/general.show_assigned_assets')) }}
</div> </div>
<div class="col-md-9"> <div class="col-md-9">
<label class="form-control">
{{ Form::checkbox('show_assigned_assets', '1', Request::old('show_assigned_assets', $setting->show_assigned_assets),array('class' => 'minimal')) }} {{ Form::checkbox('show_assigned_assets', '1', Request::old('show_assigned_assets', $setting->show_assigned_assets),array('class' => 'minimal')) }}
{{ trans('general.yes') }} {{ trans('general.yes') }}
</label>
<p class="help-block">{{ trans('admin/settings/general.show_assigned_assets_help') }}</p> <p class="help-block">{{ trans('admin/settings/general.show_assigned_assets_help') }}</p>
{!! $errors->first('show_assigned_assets', '<span class="alert-msg">:message</span>') !!} {!! $errors->first('show_assigned_assets', '<span class="alert-msg">:message</span>') !!}
</div> </div>

View file

@ -106,7 +106,7 @@
<div class="col-md-3 text-right"> <div class="col-md-3 text-right">
{{ Form::label('label2_title', trans('admin/settings/general.label2_title'), ['class'=>'control-label']) }} {{ Form::label('label2_title', trans('admin/settings/general.label2_title'), ['class'=>'control-label']) }}
</div> </div>
<div class="col-md-9"> <div class="col-md-7">
{{ Form::text('label2_title', old('label2_title', $setting->label2_title), [ 'class'=>'form-control', 'placeholder'=>$setting->qr_text, 'aria-label'=>'label2_title' ]) }} {{ Form::text('label2_title', old('label2_title', $setting->label2_title), [ 'class'=>'form-control', 'placeholder'=>$setting->qr_text, 'aria-label'=>'label2_title' ]) }}
{!! $errors->first('label2_title', '<span class="alert-msg" aria-hidden="true">:message</span>') !!} {!! $errors->first('label2_title', '<span class="alert-msg" aria-hidden="true">:message</span>') !!}
<p class="help-block">{!! trans('admin/settings/general.label2_title_help') !!}</p> <p class="help-block">{!! trans('admin/settings/general.label2_title_help') !!}</p>
@ -128,7 +128,7 @@
<label class="form-control"> <label class="form-control">
<input type="checkbox" value="1" name="label2_asset_logo"{{ ((old('label2_asset_logo') == '1') || ($setting->label2_asset_logo) == '1') ? ' checked="checked"' : '' }} aria-label="label2_asset_logo"> <input type="checkbox" value="1" name="label2_asset_logo"{{ ((old('label2_asset_logo') == '1') || ($setting->label2_asset_logo) == '1') ? ' checked="checked"' : '' }} aria-label="label2_asset_logo">
{{ trans('general.yes') }} {{ Form::label('label2_asset_logo', trans('admin/settings/general.label2_asset_logo')) }}
</label> </label>
<p class="help-block"> <p class="help-block">
{!! trans('admin/settings/general.label2_asset_logo_help', ['setting_name' => trans('admin/settings/general.brand').' &gt; '.trans('admin/settings/general.label_logo')]) !!} {!! trans('admin/settings/general.label2_asset_logo_help', ['setting_name' => trans('admin/settings/general.brand').' &gt; '.trans('admin/settings/general.label_logo')]) !!}
@ -142,7 +142,7 @@
<div class="col-md-3 text-right"> <div class="col-md-3 text-right">
{{ Form::label('label2_1d_type', trans('admin/settings/general.label2_1d_type'), ['class'=>'control-label']) }} {{ Form::label('label2_1d_type', trans('admin/settings/general.label2_1d_type'), ['class'=>'control-label']) }}
</div> </div>
<div class="col-md-9"> <div class="col-md-7">
@php @php
$select1DValues = [ $select1DValues = [
'default' => trans('admin/settings/general.default').' [ '.$setting->alt_barcode.' ]', 'default' => trans('admin/settings/general.default').' [ '.$setting->alt_barcode.' ]',
@ -174,7 +174,7 @@
<div class="col-md-3 text-right"> <div class="col-md-3 text-right">
{{ Form::label('label2_2d_type', trans('admin/settings/general.label2_2d_type'), ['class'=>'control-label']) }} {{ Form::label('label2_2d_type', trans('admin/settings/general.label2_2d_type'), ['class'=>'control-label']) }}
</div> </div>
<div class="col-md-9"> <div class="col-md-7">
@php @php
$select2DValues = [ $select2DValues = [
'default' => trans('admin/settings/general.default').' [ '.$setting->barcode_type.' ]', 'default' => trans('admin/settings/general.default').' [ '.$setting->barcode_type.' ]',

View file

@ -42,26 +42,39 @@
<!-- Language --> <!-- Language -->
<div class="form-group {{ $errors->has('site_name') ? 'error' : '' }}"> <div class="form-group {{ $errors->has('site_name') ? 'error' : '' }}">
<div class="col-md-3"> <div class="col-md-3 col-xs-12">
{{ Form::label('site_name', trans('admin/settings/general.default_language')) }} {{ Form::label('site_name', trans('admin/settings/general.default_language')) }}
</div> </div>
<div class="col-md-9"> <div class="col-md-5 col-xs-12">
{!! Form::locales('locale', Request::old('locale', $setting->locale), 'select2') !!} {!! Form::locales('locale', Request::old('locale', $setting->locale), 'select2') !!}
{!! $errors->first('locale', '<span class="alert-msg" aria-hidden="true">:message</span>') !!} {!! $errors->first('locale', '<span class="alert-msg" aria-hidden="true">:message</span>') !!}
</div> </div>
</div> </div>
<!-- name display format -->
<div class="form-group {{ $errors->has('name_display_format') ? 'error' : '' }}">
<div class="col-md-3 col-xs-12">
{{ Form::label('name_display_format', trans('general.name_display_format')) }}
</div>
<div class="col-md-5 col-xs-12">
{!! Form::name_display_format('name_display_format', Request::old('name_display_format', $setting->name_display_format), 'select2') !!}
{!! $errors->first('name_display_format', '<span class="alert-msg" aria-hidden="true">:message</span>') !!}
</div>
</div>
<!-- Date format --> <!-- Date format -->
<div class="form-group {{ $errors->has('time_display_format') ? 'error' : '' }}"> <div class="form-group {{ $errors->has('time_display_format') ? 'error' : '' }}">
<div class="col-md-3"> <div class="col-md-3 col-xs-12">
{{ Form::label('time_display_format', trans('general.time_and_date_display')) }} {{ Form::label('time_display_format', trans('general.time_and_date_display')) }}
</div> </div>
<div class="col-md-5"> <div class="col-md-5 col-xs-12">
{!! Form::date_display_format('date_display_format', Request::old('date_display_format', $setting->date_display_format), 'select2') !!} {!! Form::date_display_format('date_display_format', Request::old('date_display_format', $setting->date_display_format), 'select2') !!}
</div> </div>
<div class="col-md-3"> <div class="col-md-3 col-xs-12">
{!! Form::time_display_format('time_display_format', Request::old('time_display_format', $setting->time_display_format), 'select2') !!} {!! Form::time_display_format('time_display_format', Request::old('time_display_format', $setting->time_display_format), 'select2') !!}
</div> </div>
@ -71,10 +84,10 @@
<!-- Currency --> <!-- Currency -->
<div class="form-group {{ $errors->has('default_currency') ? 'error' : '' }}"> <div class="form-group {{ $errors->has('default_currency') ? 'error' : '' }}">
<div class="col-md-3"> <div class="col-md-3 col-xs-12">
{{ Form::label('default_currency', trans('admin/settings/general.default_currency')) }} {{ Form::label('default_currency', trans('admin/settings/general.default_currency')) }}
</div> </div>
<div class="col-md-9"> <div class="col-md-9 col-xs-12">
{{ Form::text('default_currency', old('default_currency', $setting->default_currency), array('class' => 'form-control select2-container','placeholder' => 'USD', 'maxlength'=>'3', 'style'=>'width: 60px; display: inline-block; ')) }} {{ Form::text('default_currency', old('default_currency', $setting->default_currency), array('class' => 'form-control select2-container','placeholder' => 'USD', 'maxlength'=>'3', 'style'=>'width: 60px; display: inline-block; ')) }}
{!! Form::digit_separator('digit_separator', old('digit_separator', $setting->digit_separator), 'select2') !!} {!! Form::digit_separator('digit_separator', old('digit_separator', $setting->digit_separator), 'select2') !!}
@ -84,9 +97,6 @@
</div> </div>
</div> </div>
</div> <!--/.box-body--> </div> <!--/.box-body-->