Skip to content

Commit

Permalink
Merge pull request #9529 from dampfklon/Feature_#9514_Asset_Acceptanc…
Browse files Browse the repository at this point in the history
…e,_resend_mail/_send_remainder

Feature #9514, Feature #9378 Unaccepted Assets Report Actions, Fixed [ch16410]
  • Loading branch information
snipe authored Oct 7, 2021
2 parents 3980c80 + ab4a234 commit 5f52ee5
Show file tree
Hide file tree
Showing 7 changed files with 193 additions and 51 deletions.
12 changes: 12 additions & 0 deletions app/Http/Controllers/Assets/AssetCheckinController.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
use App\Http\Controllers\Controller;
use App\Http\Requests\AssetCheckinRequest;
use App\Models\Asset;
use App\Models\CheckoutAcceptance;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Redirect;
use Illuminate\Support\Facades\View;
Expand Down Expand Up @@ -109,6 +111,16 @@ public function store(AssetCheckinRequest $request, $assetId = null, $backto = n
$checkin_at = $request->input('checkin_at');
}

// Get all pending Acceptances for this asset and delete them
$acceptances = CheckoutAcceptance::pending()->whereHasMorph('checkoutable',
[Asset::class],
function (Builder $query) use ($asset) {
$query->where('id', $asset->id);
})->get();
$acceptances->map(function($acceptance) {
$acceptance->delete();
});

// Was the asset updated?
if ($asset->save()) {
event(new CheckoutableCheckedIn($asset, $target, Auth::user(), $request->input('note'), $checkin_at));
Expand Down
149 changes: 117 additions & 32 deletions app/Http/Controllers/ReportsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@
use App\Models\Depreciation;
use App\Models\License;
use App\Models\Setting;
use App\Notifications\CheckoutAssetNotification;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Notification;
use Illuminate\Support\Facades\Response;
use Illuminate\Support\Facades\View;
use Input;
Expand Down Expand Up @@ -73,7 +75,7 @@ public function exportAccessoryReport()
trans('admin/accessories/general.remaining'),
];
$header = array_map('trim', $header);
$rows[] = implode($header, ', ');
$rows[] = implode(', ', $header);

// Row per accessory
foreach ($accessories as $accessory) {
Expand All @@ -83,10 +85,10 @@ public function exportAccessoryReport()
$row[] = e($accessory->total);
$row[] = e($accessory->remaining);

$rows[] = implode($row, ',');
$rows[] = implode(',', $row);
}

$csv = implode($rows, "\n");
$csv = implode("\n", $rows);
$response = Response::make($csv, 200);
$response->header('Content-Type', 'text/csv');
$response->header('Content-disposition', 'attachment;filename=report.csv');
Expand Down Expand Up @@ -344,7 +346,7 @@ public function exportLicenseReport()
];

$header = array_map('trim', $header);
$rows[] = implode($header, ', ');
$rows[] = implode(', ', $header);

// Row per license
foreach ($licenses as $license) {
Expand All @@ -358,10 +360,11 @@ public function exportLicenseReport()
$row[] = ($license->depreciation != '') ? '' : e($license->depreciation->name);
$row[] = '"'.Helper::formatCurrencyOutput($license->purchase_cost).'"';

$rows[] = implode($row, ',');
$rows[] = implode(',', $row);
}

$csv = implode($rows, "\n");

$csv = implode("\n", $rows);
$response = Response::make($csv, 200);
$response->header('Content-Type', 'text/csv');
$response->header('Content-disposition', 'attachment;filename=report.csv');
Expand Down Expand Up @@ -869,7 +872,7 @@ public function exportAssetMaintenancesReport()
];

$header = array_map('trim', $header);
$rows[] = implode($header, ',');
$rows[] = implode(',', $header);

foreach ($assetMaintenances as $assetMaintenance) {
$row = [];
Expand All @@ -886,13 +889,13 @@ public function exportAssetMaintenancesReport()
} else {
$improvementTime = intval($assetMaintenance->asset_maintenance_time);
}
$row[] = $improvementTime;
$row[] = trans('general.currency').Helper::formatCurrencyOutput($assetMaintenance->cost);
$rows[] = implode($row, ',');
$row[] = $improvementTime;
$row[] = trans('general.currency') . Helper::formatCurrencyOutput($assetMaintenance->cost);
$rows[] = implode(',', $row);
}

// spit out a csv
$csv = implode($rows, "\n");
$csv = implode("\n", $rows);
$response = Response::make($csv, 200);
$response->header('Content-Type', 'text/csv');
$response->header('Content-disposition', 'attachment;filename=report.csv');
Expand All @@ -904,42 +907,124 @@ public function exportAssetMaintenancesReport()
* getAssetAcceptanceReport
*
* @return mixed
* @throws \Illuminate\Auth\Access\AuthorizationException
* @author Vincent Sposato <[email protected]>
* @version v1.0
*/
public function getAssetAcceptanceReport()
public function getAssetAcceptanceReport($deleted = false)
{
$this->authorize('reports.view');
$showDeleted = $deleted == 'deleted';

/**
* Get all assets with pending checkout acceptances
*/
$acceptances = CheckoutAcceptance::pending()->get();
if($showDeleted) {
$acceptances = CheckoutAcceptance::pending()->withTrashed()->with(['assignedTo' , 'checkoutable.assignedTo', 'checkoutable.model'])->get();
} else {
$acceptances = CheckoutAcceptance::pending()->with(['assignedTo' => function ($query) {
$query->withTrashed();
}, 'checkoutable.assignedTo', 'checkoutable.model'])->get();
}

$assetsForReport = $acceptances
->filter(function ($acceptance) {
return $acceptance->checkoutable_type == \App\Models\Asset::class;
})
->map(function ($acceptance) {
return $acceptance->checkoutable;
->map(function($acceptance) {
return ['assetItem' => $acceptance->checkoutable, 'acceptance' => $acceptance];
});

return view('reports/unaccepted_assets', compact('assetsForReport'));
return view('reports/unaccepted_assets', compact('assetsForReport','showDeleted' ));
}

/**
* sentAssetAcceptanceReminder
*
* @param integer|null $acceptanceId
* @return \Illuminate\Http\RedirectResponse
* @throws \Illuminate\Auth\Access\AuthorizationException
* @version v1.0
*/
public function sentAssetAcceptanceReminder($acceptanceId = null)
{
$this->authorize('reports.view');

if (!$acceptance = CheckoutAcceptance::pending()->find($acceptanceId)) {
// Redirect to the unaccepted assets report page with error
return redirect()->route('reports/unaccepted_assets')->with('error', trans('general.bad_data'));
}
$assetItem = $acceptance->checkoutable;

$logItem = $assetItem->checkouts()->where('created_at', '=', $acceptance->created_at)->get()[0];

if(!$assetItem->assignedTo->locale){
Notification::locale(Setting::getSettings()->locale)->send(
$assetItem->assignedTo,
new CheckoutAssetNotification($assetItem, $assetItem->assignedTo, $logItem->user, $acceptance, $logItem->note)
);
} else {
Notification::send(
$assetItem->assignedTo,
new CheckoutAssetNotification($assetItem, $assetItem->assignedTo, $logItem->user, $acceptance, $logItem->note)
);
}

return redirect()->route('reports/unaccepted_assets')->with('success', trans('admin/reports/general.reminder_sent'));
}

/**
* sentAssetAcceptanceReminder
*
* @param integer|null $acceptanceId
* @return \Illuminate\Http\RedirectResponse
* @throws \Illuminate\Auth\Access\AuthorizationException
* @version v1.0
*/
public function deleteAssetAcceptance($acceptanceId = null)
{
$this->authorize('reports.view');

if (!$acceptance = CheckoutAcceptance::pending()->find($acceptanceId)) {
// Redirect to the unaccepted assets report page with error
return redirect()->route('reports/unaccepted_assets')->with('error', trans('general.bad_data'));
}

if($acceptance->delete()) {
return redirect()->route('reports/unaccepted_assets')->with('success', trans('admin/reports/general.acceptance_deleted'));
} else {
return redirect()->route('reports/unaccepted_assets')->with('error', trans('general.deletion_failed'));
}
}

/**
* exportAssetAcceptanceReport
* Exports the AssetAcceptance report to CSV
*
* @return \Illuminate\Http\Response
* @author Vincent Sposato <[email protected]>
* @version v1.0
*/
public function exportAssetAcceptanceReport()
public function postAssetAcceptanceReport($deleted = false)
{
$this->authorize('reports.view');
// Grab all the improvements
$assetsForReport = Actionlog::whereIn('id', $this->getAssetsNotAcceptedYet())
->get();
$showDeleted = $deleted == 'deleted';

/**
* Get all assets with pending checkout acceptances
*/
if($showDeleted) {
$acceptances = CheckoutAcceptance::pending()->withTrashed()->with(['assignedTo', 'checkoutable.assignedTo', 'checkoutable.model'])->get();
} else {
$acceptances = CheckoutAcceptance::pending()->with(['assignedTo', 'checkoutable.assignedTo', 'checkoutable.model'])->get();
}

$assetsForReport = $acceptances
->filter(function($acceptance) {
return $acceptance->checkoutable_type == 'App\Models\Asset';
})
->map(function($acceptance) {
return ['assetItem' => $acceptance->checkoutable, 'acceptance' => $acceptance];
});

$rows = [];

Expand All @@ -952,20 +1037,20 @@ public function exportAssetAcceptanceReport()
];

$header = array_map('trim', $header);
$rows[] = implode($header, ',');

foreach ($assetsForReport as $assetItem) {
$row = [];
$row[] = str_replace(',', '', e($assetItem->assetlog->model->category->name));
$row[] = str_replace(',', '', e($assetItem->assetlog->model->name));
$row[] = str_replace(',', '', e($assetItem->assetlog->present()->name()));
$row[] = str_replace(',', '', e($assetItem->assetlog->asset_tag));
$row[] = str_replace(',', '', e($assetItem->assetlog->assignedTo->present()->name()));
$rows[] = implode($row, ',');
$rows[] = implode(',', $header);

foreach ($assetsForReport as $item) {
$row = [ ];
$row[] = str_replace(',', '', e($item['assetItem']->model->category->name));
$row[] = str_replace(',', '', e($item['assetItem']->model->name));
$row[] = str_replace(',', '', e($item['assetItem']->name));
$row[] = str_replace(',', '', e($item['assetItem']->asset_tag));
$row[] = str_replace(',', '', e(($item['acceptance']->assignedTo) ? $item['acceptance']->assignedTo->present()->name() : trans('admin/reports/general.deleted_user')));
$rows[] = implode(',', $row);
}

// spit out a csv
$csv = implode($rows, "\n");
$csv = implode("\n", $rows);
$response = Response::make($csv, 200);
$response->header('Content-Type', 'text/csv');
$response->header('Content-disposition', 'attachment;filename=report.csv');
Expand Down
1 change: 1 addition & 0 deletions app/Notifications/CheckoutAssetNotification.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace App\Notifications;

use App\Helpers\Helper;
use App\Models\Asset;
use App\Models\Setting;
use App\Models\User;
Expand Down
7 changes: 6 additions & 1 deletion resources/lang/en/admin/reports/general.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,9 @@

return [
'info' => 'Select the options you want for your asset report.',
];
'deleted_user' => 'Deleted user',
'send_reminder' => 'Send reminder',
'reminder_sent' => 'Reminder sent',
'acceptance_deleted' => 'Acceptance request deleted',
'acceptance_request' => 'Acceptance request'
];
2 changes: 2 additions & 0 deletions resources/lang/en/general.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
'delete_confirm' => 'Are you sure you wish to delete :item?',
'deleted' => 'Deleted',
'delete_seats' => 'Deleted Seats',
'deletion_failed' => 'Deletion failed',
'departments' => 'Departments',
'department' => 'Department',
'deployed' => 'Deployed',
Expand Down Expand Up @@ -247,4 +248,5 @@
'show_help' => 'Show help',
'hide_help' => 'Hide help',
'view_all' => 'view all',
'hide_deleted' => 'Hide Deleted',
];
59 changes: 44 additions & 15 deletions resources/views/reports/unaccepted_assets.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,25 @@
@parent
@stop

@section('header_right')

<div class="btn-toolbar" role="toolbar">
<div class="btn-group mr-2" role="group">
@if($showDeleted)
<a href="{{ route('reports/unaccepted_assets') }}" class="btn btn-default" ><i class="fa fa-trash icon-white" aria-hidden="true"></i> {{ trans('general.hide_deleted') }}</a>
@else
<a href="{{ route('reports/unaccepted_assets', ['deleted' => 'deleted']) }}" class="btn btn-default" ><i class="fa fa-trash icon-white" aria-hidden="true"></i> {{ trans('general.show_deleted') }}</a>
@endif
</div>
<div class="btn-group mr-2" role="group">
{{ Form::open(['method' => 'post', 'class' => 'form-horizontal']) }}
{{csrf_field()}}
<button type="submit" class="btn btn-default"><i class="fa fa-download icon-white" aria-hidden="true"></i> {{ trans('general.download_all') }}</button>
{{ Form::close() }}
</div>
</div>
@stop

{{-- Page content --}}
@section('content')

Expand All @@ -27,6 +46,7 @@
data-show-export="true"
data-show-refresh="true"
data-sort-order="asc"
data-sort-name="created_at"
id="unacceptedAssetsReport"
class="table table-striped snipe-table"
data-export-options='{
Expand All @@ -35,25 +55,34 @@ class="table table-striped snipe-table"
}'>
<thead>
<tr role="row">
<th class="col-sm-1">{{ trans('admin/companies/table.title') }}</th>
<th class="col-sm-1">{{ trans('general.category') }}</th>
<th class="col-sm-1">{{ trans('admin/hardware/form.model') }}</th>
<th class="col-sm-1">{{ trans('admin/hardware/form.name') }}</th>
<th class="col-sm-1">{{ trans('admin/hardware/table.asset_tag') }}</th>
<th class="col-sm-1">{{ trans('admin/hardware/table.checkoutto') }}</th>
<th class="col-sm-1" data-searchable="false" data-field="created_at" data-sortable="true">{{ trans('general.date') }}</th>
<th class="col-sm-1" data-sortable="true" >{{ trans('admin/companies/table.title') }}</th>
<th class="col-sm-1" data-sortable="true" >{{ trans('general.category') }}</th>
<th class="col-sm-1" data-sortable="true" >{{ trans('admin/hardware/form.model') }}</th>
<th class="col-sm-1" data-sortable="true" >{{ trans('admin/hardware/form.name') }}</th>
<th class="col-sm-1" data-sortable="true" >{{ trans('admin/hardware/table.asset_tag') }}</th>
<th class="col-sm-1" data-sortable="true" >{{ trans('admin/hardware/table.checkoutto') }}</th>
<th class="col-md-1"><span class="line"></span>{{ trans('table.actions') }}</th>
</tr>
</thead>
<tbody>
@if ($assetsForReport)
@foreach ($assetsForReport as $assetItem)
@if ($assetItem)
<tr>
<td>{{ ($assetItem->company) ? $assetItem->company->name : '' }}</td>
<td>{{ $assetItem->model->category->name }}</td>
<td>{{ $assetItem->model->name }}</td>
<td>{!! $assetItem->present()->nameUrl() !!}</td>
<td>{{ $assetItem->asset_tag }}</td>
<td>{!! ($assetItem->assignedTo) ? $assetItem->assignedTo->present()->nameUrl() : 'Deleted user' !!}</td>
@foreach ($assetsForReport as $item)
@if ($item['assetItem'])
<tr @if($item['acceptance']->trashed()) style="text-decoration: line-through" @endif>
<td>{{ $item['acceptance']->created_at }}</td>
<td>{{ ($item['assetItem']->company) ? $assetItem->company->name : '' }}</td>
<td>{!! $item['assetItem']->model->category->present()->nameUrl() !!}</td>
<td>{!! $item['assetItem']->present()->modelUrl() !!}</td>
<td>{!! $item['assetItem']->present()->nameUrl() !!}</td>
<td>{{ $item['assetItem']->asset_tag }}</td>
<td @if($item['acceptance']->assignedTo === null || $item['acceptance']->assignedTo->trashed()) style="text-decoration: line-through" @endif>{!! ($item['acceptance']->assignedTo) ? $item['acceptance']->assignedTo->present()->nameUrl() : trans('admin/reports/general.deleted_user') !!}</td>
<td>
@if(!$item['acceptance']->trashed())
@if ($item['acceptance']->assignedTo)<a href="{{ route('reports/unaccepted_assets_sent_reminder', ['acceptanceId' => $item['acceptance']->id]) }}" class="btn btn-sm bg-purple" data-tooltip="true">{{ trans('admin/reports/general.send_reminder') }}</a>@endif
<a href="{{ route('reports/unaccepted_assets_delete', ['acceptanceId' => $item['acceptance']->id]) }}" class="btn btn-sm btn-danger delete-asset" data-tooltip="true" data-toggle="modal" data-content="{{ trans('general.delete_confirm', ['item' =>trans('admin/reports/general.acceptance_request')]) }}" data-title="{{ trans('general.delete') }}" onClick="return false;"><i class="fa fa-trash"></i></a>
@endif
</td>
</tr>
@endif
@endforeach
Expand Down
Loading

0 comments on commit 5f52ee5

Please sign in to comment.