Skip to content

Commit dd2b570

Browse files
committed
Added tighter constraints on deleting components
Signed-off-by: snipe <[email protected]>
1 parent 2bee453 commit dd2b570

File tree

4 files changed

+35
-6
lines changed

4 files changed

+35
-6
lines changed

app/Http/Controllers/Api/ComponentsController.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ public function index(Request $request) : JsonResponse | array
4848
];
4949

5050
$components = Component::select('components.*')
51-
->with('company', 'location', 'category', 'assets', 'supplier', 'adminuser', 'manufacturer');
51+
->with('company', 'location', 'category', 'assets', 'supplier', 'adminuser', 'manufacturer', 'uncontrainedAssets')
52+
->withSum('uncontrainedAssets', 'components_assets.assigned_qty');
5253

5354
if ($request->filled('search')) {
5455
$components = $components->TextSearch($request->input('search'));
@@ -197,6 +198,11 @@ public function destroy($id) : JsonResponse
197198
$this->authorize('delete', Component::class);
198199
$component = Component::findOrFail($id);
199200
$this->authorize('delete', $component);
201+
202+
if ($component->numCheckedOut() > 0) {
203+
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/components/message.delete.error_qty')));
204+
}
205+
200206
$component->delete();
201207

202208
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/components/message.delete.success')));

app/Http/Controllers/Components/ComponentsController.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,10 @@ public function destroy($componentId)
196196
}
197197
}
198198

199+
if ($component->numCheckedOut() > 0) {
200+
return redirect()->route('components.index')->with('error', trans('admin/components/message.delete.error_qty'));
201+
}
202+
199203
$component->delete();
200204

201205
return redirect()->route('components.index')->with('success', trans('admin/components/message.delete.success'));

app/Http/Transformers/ComponentsTransformer.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ public function transformComponent(Component $component)
6262
'checkout' => Gate::allows('checkout', Component::class),
6363
'checkin' => Gate::allows('checkin', Component::class),
6464
'update' => Gate::allows('update', Component::class),
65-
'delete' => Gate::allows('delete', Component::class),
65+
'delete' => $component->isDeletable(),
6666
];
6767
$array += $permissions_array;
6868

app/Models/Component.php

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use App\Presenters\Presentable;
77
use Illuminate\Database\Eloquent\Factories\HasFactory;
88
use Illuminate\Database\Eloquent\SoftDeletes;
9+
use Illuminate\Support\Facades\Gate;
910
use Watson\Validating\ValidatingTrait;
1011

1112
/**
@@ -104,6 +105,13 @@ class Component extends SnipeModel
104105
];
105106

106107

108+
public function isDeletable()
109+
{
110+
return Gate::allows('delete', $this)
111+
&& ($this->numCheckedOut() === 0)
112+
&& ($this->deleted_at == '');
113+
}
114+
107115
/**
108116
* Establishes the components -> action logs -> uploads relationship
109117
*
@@ -234,13 +242,24 @@ public function numCheckedOut()
234242
// In case there are elements checked out to assets that belong to a different company
235243
// than this asset and full multiple company support is on we'll remove the global scope,
236244
// so they are included in the count.
237-
foreach ($this->assets()->withoutGlobalScope(new CompanyableScope)->get() as $checkout) {
238-
$checkedout += $checkout->pivot->assigned_qty;
239-
}
245+
return $this->uncontrainedAssets->sum('pivot.assigned_qty');
246+
}
247+
248+
249+
/**
250+
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
251+
*
252+
* This allows us to get the assets with assigned components without the company restriction
253+
*/
254+
public function uncontrainedAssets() {
255+
256+
return $this->belongsToMany(\App\Models\Asset::class, 'components_assets')
257+
->withPivot('id', 'assigned_qty', 'created_at', 'created_by', 'note')
258+
->withoutGlobalScope(new CompanyableScope);
240259

241-
return $checkedout;
242260
}
243261

262+
244263
/**
245264
* Check how many items within a component are remaining
246265
*

0 commit comments

Comments
 (0)