mirror of
https://github.com/snipe/snipe-it.git
synced 2024-11-10 15:44:11 -08:00
Merge pull request #11650 from snipe/fixes/6877_add_notes_to_consumables
Fixed #6877 - Added notes to consumables, components on checkout
This commit is contained in:
commit
c77d763f05
|
@ -246,7 +246,8 @@ class ComponentsController extends Controller
|
|||
'created_at' => \Carbon::now(),
|
||||
'assigned_qty' => $request->get('assigned_qty', 1),
|
||||
'user_id' => \Auth::id(),
|
||||
'asset_id' => $request->get('assigned_to')
|
||||
'asset_id' => $request->get('assigned_to'),
|
||||
'note' => $request->get('note'),
|
||||
]);
|
||||
|
||||
$component->logCheckout($request->input('note'), $asset);
|
||||
|
|
|
@ -230,7 +230,8 @@ class ConsumablesController extends Controller
|
|||
$rows[] = [
|
||||
'name' => ($consumable_assignment->user) ? $consumable_assignment->user->present()->nameUrl() : 'Deleted User',
|
||||
'created_at' => Helper::getFormattedDateObject($consumable_assignment->created_at, 'datetime'),
|
||||
'admin' => ($consumable_assignment->admin) ? $consumable_assignment->admin->present()->nameUrl() : '',
|
||||
'note' => ($consumable_assignment->note) ? e($consumable_assignment->note) : null,
|
||||
'admin' => ($consumable_assignment->admin) ? $consumable_assignment->admin->present()->nameUrl() : null,
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -273,6 +274,7 @@ class ConsumablesController extends Controller
|
|||
'consumable_id' => $consumable->id,
|
||||
'user_id' => $user->id,
|
||||
'assigned_to' => $assigned_to,
|
||||
'note' => $request->input('note'),
|
||||
]);
|
||||
|
||||
// Log checkout event
|
||||
|
|
|
@ -87,6 +87,7 @@ class ComponentCheckoutController extends Controller
|
|||
'created_at' => date('Y-m-d H:i:s'),
|
||||
'assigned_qty' => $request->input('assigned_qty'),
|
||||
'asset_id' => $asset_id,
|
||||
'note' => $request->input('note'),
|
||||
]);
|
||||
|
||||
event(new CheckoutableCheckedOut($component, $asset, Auth::user(), $request->input('note')));
|
||||
|
|
|
@ -56,7 +56,7 @@ class ConsumableCheckoutController extends Controller
|
|||
// Check if the user exists
|
||||
if (is_null($user = User::find($assigned_to))) {
|
||||
// Redirect to the consumable management page with error
|
||||
return redirect()->route('consumables.checkout.show', $consumable)->with('error', trans('admin/consumables/message.checkout.user_does_not_exist'));
|
||||
return redirect()->route('consumables.checkout.show', $consumable)->with('error', trans('admin/consumables/message.checkout.user_does_not_exist'))->withInput();
|
||||
}
|
||||
|
||||
// Update the consumable data
|
||||
|
@ -66,6 +66,7 @@ class ConsumableCheckoutController extends Controller
|
|||
'consumable_id' => $consumable->id,
|
||||
'user_id' => $admin_user->id,
|
||||
'assigned_to' => e($request->input('assigned_to')),
|
||||
'note' => $request->input('note'),
|
||||
]);
|
||||
|
||||
event(new CheckoutableCheckedOut($consumable, $user, Auth::user(), $request->input('note')));
|
||||
|
|
|
@ -26,6 +26,7 @@ class ComponentsAssetsTransformer
|
|||
'created_at' => $asset->created_at->format('Y-m-d'),
|
||||
'qty' => $asset->components()->count(),
|
||||
'user_can_checkout' => $asset->availableForCheckout(),
|
||||
'note' => e($asset->note),
|
||||
];
|
||||
|
||||
$permissions_array['available_actions'] = [
|
||||
|
|
|
@ -71,6 +71,7 @@ class ComponentsTransformer
|
|||
'id' => (int) $asset->id,
|
||||
'name' => e($asset->model->present()->name).' '.e($asset->present()->name),
|
||||
'qty' => $asset->pivot->assigned_qty,
|
||||
'note' => $asset->pivot->note,
|
||||
'type' => 'asset',
|
||||
'created_at' => Helper::getFormattedDateObject($asset->pivot->created_at, 'datetime'),
|
||||
'available_actions' => ['checkin' => true],
|
||||
|
|
|
@ -109,7 +109,7 @@ class Component extends SnipeModel
|
|||
*/
|
||||
public function assets()
|
||||
{
|
||||
return $this->belongsToMany(\App\Models\Asset::class, 'components_assets')->withPivot('id', 'assigned_qty', 'created_at', 'user_id');
|
||||
return $this->belongsToMany(\App\Models\Asset::class, 'components_assets')->withPivot('id', 'assigned_qty', 'created_at', 'user_id', 'note');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -308,7 +308,7 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
|
|||
*/
|
||||
public function consumables()
|
||||
{
|
||||
return $this->belongsToMany(\App\Models\Consumable::class, 'consumables_users', 'assigned_to', 'consumable_id')->withPivot('id','created_at')->withTrashed();
|
||||
return $this->belongsToMany(\App\Models\Consumable::class, 'consumables_users', 'assigned_to', 'consumable_id')->withPivot('id','created_at','note')->withTrashed();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class AddNotesDenormToConsumablesUsers extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('consumables_users', function (Blueprint $table) {
|
||||
$table->text('note')->nullable()->default(null);
|
||||
});
|
||||
|
||||
Schema::table('components_assets', function (Blueprint $table) {
|
||||
$table->text('note')->nullable()->default(null);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('consumables_users', function (Blueprint $table) {
|
||||
if (Schema::hasColumn('consumables_users', 'note')) {
|
||||
$table->dropColumn('note');
|
||||
}
|
||||
});
|
||||
|
||||
Schema::table('components_assets', function (Blueprint $table) {
|
||||
if (Schema::hasColumn('components_assets', 'note')) {
|
||||
$table->dropColumn('note');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -171,7 +171,7 @@
|
|||
@can('checkout', \App\Models\Accessory::class)
|
||||
<div class="row">
|
||||
<div class="col-md-12 text-center">
|
||||
<a href="{{ route('accessories.checkout.show', $accessory->id) }}" style="margin-right:5px;" class="btn btn-primary btn-sm" {{ (($accessory->numRemaining() > 0 ) ? '' : ' disabled') }}>{{ trans('general.checkout') }}</a>
|
||||
<a href="{{ route('accessories.checkout.show', $accessory->id) }}" style="margin-right:5px; width:100%" class="btn btn-primary btn-sm" {{ (($accessory->numRemaining() > 0 ) ? '' : ' disabled') }}>{{ trans('general.checkout') }}</a>
|
||||
</div>
|
||||
</div>
|
||||
@endcan
|
||||
|
|
|
@ -47,6 +47,15 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Note -->
|
||||
<div class="form-group {{ $errors->has('note') ? 'error' : '' }}">
|
||||
<label for="note" class="col-md-3 control-label">{{ trans('admin/hardware/form.notes') }}</label>
|
||||
<div class="col-md-7">
|
||||
<textarea class="col-md-6 form-control" id="note" name="note">{{ old('note', $component->note) }}</textarea>
|
||||
{!! $errors->first('note', '<span class="alert-msg" aria-hidden="true"><i class="fas fa-times" aria-hidden="true"></i> :message</span>') !!}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div> <!-- .BOX-BODY-->
|
||||
<div class="box-footer">
|
||||
|
|
|
@ -87,6 +87,9 @@
|
|||
<th data-searchable="false" data-sortable="false" data-field="qty">
|
||||
{{ trans('general.qty') }}
|
||||
</th>
|
||||
<th data-searchable="false" data-sortable="false" data-field="note">
|
||||
{{ trans('general.notes') }}
|
||||
</th>
|
||||
<th data-searchable="false" data-sortable="false" data-field="created_at" data-formatter="dateDisplayFormatter">
|
||||
{{ trans('general.date') }}
|
||||
</th>
|
||||
|
|
|
@ -70,13 +70,13 @@
|
|||
<div class="form-group {{ $errors->has('note') ? 'error' : '' }}">
|
||||
<label for="note" class="col-md-3 control-label">{{ trans('admin/hardware/form.notes') }}</label>
|
||||
<div class="col-md-7">
|
||||
<textarea class="col-md-6 form-control" id="note" name="note">{{ old('note', $consumable->note) }}</textarea>
|
||||
<textarea class="col-md-6 form-control" name="note">{{ old('note') }}</textarea>
|
||||
{!! $errors->first('note', '<span class="alert-msg" aria-hidden="true"><i class="fas fa-times" aria-hidden="true"></i> :message</span>') !!}
|
||||
</div>
|
||||
</div>
|
||||
</div> <!-- .box-body -->
|
||||
<div class="box-footer">
|
||||
<a class="btn btn-link" href="{{ URL::previous() }}">{{ trans('button.cancel') }}</a>
|
||||
<a class="btn btn-link" href="{{ route('consumables.show', ['consumable'=> $consumable->id]) }}">{{ trans('button.cancel') }}</a>
|
||||
<button type="submit" class="btn btn-primary pull-right"><i class="fas fa-check icon-white" aria-hidden="true"></i> {{ trans('general.checkout') }}</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -55,6 +55,7 @@
|
|||
<tr>
|
||||
<th data-searchable="false" data-sortable="false" data-field="name">{{ trans('general.user') }}</th>
|
||||
<th data-searchable="false" data-sortable="false" data-field="created_at" data-formatter="dateDisplayFormatter">{{ trans('general.date') }}</th>
|
||||
<th data-searchable="false" data-sortable="false" data-field="note">{{ trans('general.notes') }}</th>
|
||||
<th data-searchable="false" data-sortable="false" data-field="admin">{{ trans('general.admin') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
@ -76,21 +77,21 @@
|
|||
|
||||
|
||||
@if ($consumable->image!='')
|
||||
<div class="col-md-12 text-center" style="padding-bottom: 15px;">
|
||||
<div class="col-md-12 text-center">
|
||||
<a href="{{ Storage::disk('public')->url('consumables/'.e($consumable->image)) }}" data-toggle="lightbox">
|
||||
<img src="{{ Storage::disk('public')->url('consumables/'.e($consumable->image)) }}" class="img-responsive img-thumbnail" alt="{{ $consumable->name }}"></a>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if ($consumable->purchase_date)
|
||||
<div class="col-md-12" style="padding-bottom: 15px;">
|
||||
<div class="col-md-12">
|
||||
<strong>{{ trans('general.purchase_date') }}: </strong>
|
||||
{{ Helper::getFormattedDateObject($consumable->purchase_date, 'date', false) }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if ($consumable->purchase_cost)
|
||||
<div class="col-md-12" style="padding-bottom: 15px;">
|
||||
<div class="col-md-12">
|
||||
<strong>{{ trans('general.purchase_cost') }}:</strong>
|
||||
{{ $snipeSettings->default_currency }}
|
||||
{{ Helper::formatCurrencyOutput($consumable->purchase_cost) }}
|
||||
|
@ -98,28 +99,28 @@
|
|||
@endif
|
||||
|
||||
@if ($consumable->item_no)
|
||||
<div class="col-md-12" style="padding-bottom: 15px;">
|
||||
<div class="col-md-12">
|
||||
<strong>{{ trans('admin/consumables/general.item_no') }}:</strong>
|
||||
{{ $consumable->item_no }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if ($consumable->model_number)
|
||||
<div class="col-md-12" style="padding-bottom: 15px;">
|
||||
<div class="col-md-12">
|
||||
<strong>{{ trans('general.model_no') }}:</strong>
|
||||
{{ $consumable->model_number }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if ($consumable->manufacturer)
|
||||
<div class="col-md-12" style="padding-bottom: 15px;">
|
||||
<div class="col-md-12">
|
||||
<strong>{{ trans('general.manufacturer') }}:</strong>
|
||||
<a href="{{ route('manufacturers.show', $consumable->manufacturer->id) }}">{{ $consumable->manufacturer->name }}</a>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if ($consumable->order_number)
|
||||
<div class="col-md-12" style="padding-bottom: 15px;">
|
||||
<div class="col-md-12">
|
||||
<strong>{{ trans('general.order_number') }}:</strong>
|
||||
{{ $consumable->order_number }}
|
||||
</div>
|
||||
|
@ -128,13 +129,13 @@
|
|||
@can('checkout', \App\Models\Consumable::class)
|
||||
|
||||
<div class="col-md-12">
|
||||
|
||||
<br><br>
|
||||
@if ($consumable->numRemaining() > 0)
|
||||
<a href="{{ route('consumables.checkout.show', $consumable->id) }}" style="padding-bottom:5px;" class="btn btn-primary btn-sm">
|
||||
<a href="{{ route('consumables.checkout.show', $consumable->id) }}" style="margin-bottom:10px; width:100%" class="btn btn-primary btn-sm">
|
||||
{{ trans('general.checkout') }}
|
||||
</a>
|
||||
@else
|
||||
<button style="padding-bottom:5px;" class="btn btn-primary btn-sm disabled">
|
||||
<button style="margin-bottom:10px; width:100%"" class="btn btn-primary btn-sm disabled">
|
||||
{{ trans('general.checkout') }}
|
||||
</button>
|
||||
@endif
|
||||
|
@ -146,7 +147,7 @@
|
|||
|
||||
<div class="col-md-12">
|
||||
<strong>
|
||||
{{ trans('general.notes') }}
|
||||
{{ trans('general.notes') }}:
|
||||
</strong>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
|
|
|
@ -763,9 +763,10 @@
|
|||
}'>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="col-md-6">{{ trans('general.name') }}</th>
|
||||
<th class="col-md-3">{{ trans('general.name') }}</th>
|
||||
<th class="col-md-2" data-footer-formatter="sumFormatter" data-fieldname="purchase_cost">{{ trans('general.purchase_cost') }}</th>
|
||||
<th class="col-md-4">{{ trans('general.date') }}</th>
|
||||
<th class="col-md-2">{{ trans('general.date') }}</th>
|
||||
<th class="col-md-5">{{ trans('general.notes') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
@ -775,7 +776,8 @@
|
|||
<td>
|
||||
{!! Helper::formatCurrencyOutput($consumable->purchase_cost) !!}
|
||||
</td>
|
||||
<td>{{ $consumable->pivot->created_at }}</td>
|
||||
<td>{{ Helper::getFormattedDateObject($consumable->pivot->created_at, 'datetime', false) }}</td>
|
||||
<td>{{ $consumable->pivot->note }}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
|
|
|
@ -280,13 +280,22 @@ Route::group(['prefix' => 'v1', 'middleware' => ['api', 'throttle:api']], functi
|
|||
]
|
||||
)->name('api.consumables.selectlist');
|
||||
|
||||
Route::get('view/{id}/users',
|
||||
Route::get('{id}/users',
|
||||
[
|
||||
Api\ConsumablesController::class,
|
||||
'getDataView'
|
||||
]
|
||||
)->name('api.consumables.showUsers');
|
||||
|
||||
|
||||
// This is LEGACY endpoint URL and should be removed in the next major release
|
||||
Route::get('view/{id}/users',
|
||||
[
|
||||
Api\ConsumablesController::class,
|
||||
'getDataView'
|
||||
]
|
||||
)->name('api.consumables.showUsers');
|
||||
|
||||
Route::post('{consumable}/checkout',
|
||||
[
|
||||
Api\ConsumablesController::class,
|
||||
|
|
Loading…
Reference in a new issue