diff --git a/app/Http/Controllers/Api/DepreciationsController.php b/app/Http/Controllers/Api/DepreciationsController.php index 93088bb04a..0209eae392 100644 --- a/app/Http/Controllers/Api/DepreciationsController.php +++ b/app/Http/Controllers/Api/DepreciationsController.php @@ -20,9 +20,9 @@ class DepreciationsController extends Controller public function index(Request $request) : JsonResponse | array { $this->authorize('view', Depreciation::class); - $allowed_columns = ['id','name','months','depreciation_min','created_at']; + $allowed_columns = ['id','name','months','depreciation_min', 'depreciation_type','created_at']; - $depreciations = Depreciation::select('id','name','months','depreciation_min','user_id','created_at','updated_at'); + $depreciations = Depreciation::select('id','name','months','depreciation_min','depreciation_type','user_id','created_at','updated_at'); if ($request->filled('search')) { $depreciations = $depreciations->TextSearch($request->input('search')); diff --git a/app/Http/Controllers/DepreciationsController.php b/app/Http/Controllers/DepreciationsController.php index 57ad35fea5..c564cc98f7 100755 --- a/app/Http/Controllers/DepreciationsController.php +++ b/app/Http/Controllers/DepreciationsController.php @@ -62,6 +62,20 @@ class DepreciationsController extends Controller $depreciation->name = $request->input('name'); $depreciation->months = $request->input('months'); $depreciation->user_id = Auth::id(); + + $request->validate([ + 'depreciation_min' => [ + 'required', + 'numeric', + function ($attribute, $value, $fail) use ($request) { + if ($request->input('depreciation_type') == 'percent' && ($value < 0 || $value > 100)) { + $fail(trans('validation.percent')); + } + }, + ], + 'depreciation_type' => 'required|in:amount,percent', + ]); + $depreciation->depreciation_type = $request->input('depreciation_type'); $depreciation->depreciation_min = $request->input('depreciation_min'); // Was the asset created? @@ -116,6 +130,20 @@ class DepreciationsController extends Controller // Depreciation data $depreciation->name = $request->input('name'); $depreciation->months = $request->input('months'); + + $request->validate([ + 'depreciation_min' => [ + 'required', + 'numeric', + function ($attribute, $value, $fail) use ($request) { + if ($request->input('depreciation_type') == 'percent' && ($value < 0 || $value > 100)) { + $fail(trans('validation.percent')); + } + }, + ], + 'depreciation_type' => 'required|in:amount,percent', + ]); + $depreciation->depreciation_type = $request->input('depreciation_type'); $depreciation->depreciation_min = $request->input('depreciation_min'); // Was the asset created? diff --git a/app/Http/Transformers/DepreciationsTransformer.php b/app/Http/Transformers/DepreciationsTransformer.php index 78a01b4c1e..87e2ddaca4 100644 --- a/app/Http/Transformers/DepreciationsTransformer.php +++ b/app/Http/Transformers/DepreciationsTransformer.php @@ -7,6 +7,7 @@ use App\Models\Depreciable; use App\Models\Depreciation; use Illuminate\Support\Facades\Gate; use Illuminate\Database\Eloquent\Collection; +use Illuminate\Support\Facades\Log; class DepreciationsTransformer { @@ -26,7 +27,7 @@ class DepreciationsTransformer 'id' => (int) $depreciation->id, 'name' => e($depreciation->name), 'months' => $depreciation->months.' '.trans('general.months'), - 'depreciation_min' => $depreciation->depreciation_min, + 'depreciation_min' => $depreciation->depreciation_type === 'percent' ? $depreciation->depreciation_min.'%' : $depreciation->depreciation_min, 'created_at' => Helper::getFormattedDateObject($depreciation->created_at, 'datetime'), 'updated_at' => Helper::getFormattedDateObject($depreciation->updated_at, 'datetime') ]; diff --git a/app/Models/Depreciable.php b/app/Models/Depreciable.php index 6139cda089..0c513a3d33 100644 --- a/app/Models/Depreciable.php +++ b/app/Models/Depreciable.php @@ -76,9 +76,9 @@ class Depreciable extends SnipeModel if ($months_passed >= $this->get_depreciation()->months){ //if there is a floor use it - if(!$this->get_depreciation()->depreciation_min == null) { + if($this->get_depreciation()->depreciation_min) { - $current_value = $this->get_depreciation()->depreciation_min; + $current_value = $this->calculateDepreciation(); }else{ $current_value = 0; @@ -86,7 +86,7 @@ class Depreciable extends SnipeModel } else { // The equation here is (Purchase_Cost-Floor_min)*(Months_passed/Months_til_depreciated) - $current_value = round(($this->purchase_cost-($this->purchase_cost - ($this->get_depreciation()->depreciation_min)) * ($months_passed / $this->get_depreciation()->months)), 2); + $current_value = round(($this->purchase_cost-($this->purchase_cost - ($this->calculateDepreciation())) * ($months_passed / $this->get_depreciation()->months)), 2); } @@ -95,7 +95,7 @@ class Depreciable extends SnipeModel public function getMonthlyDepreciation(){ - return ($this->purchase_cost-$this->get_depreciation()->depreciation_min)/$this->get_depreciation()->months; + return ($this->purchase_cost-$this->calculateDepreciation())/$this->get_depreciation()->months; } @@ -191,4 +191,16 @@ class Depreciable extends SnipeModel { return new \DateTime($time); } + + private function calculateDepreciation() + { + if($this->get_depreciation()->depreciation_type === 'percent') { + $depreciation_percent= $this->get_depreciation()->depreciation_min / 100; + $depreciation_min= $this->purchase_cost * $depreciation_percent; + return $depreciation_min; + } + + $depreciation_min = $this->get_depreciation()->depreciation_min; + return $depreciation_min; + } } diff --git a/database/migrations/2024_07_16_184145_add_deprecitation_type_to_depreciations_table.php b/database/migrations/2024_07_16_184145_add_deprecitation_type_to_depreciations_table.php new file mode 100644 index 0000000000..1a5355f739 --- /dev/null +++ b/database/migrations/2024_07_16_184145_add_deprecitation_type_to_depreciations_table.php @@ -0,0 +1,28 @@ +string('depreciation_type')->after('depreciation_min')->default('amount'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('depreciations', function (Blueprint $table) { + $table->dropColumn('depreciation_type'); + }); + } +}; diff --git a/resources/lang/en-US/validation.php b/resources/lang/en-US/validation.php index c358700e95..6341707914 100644 --- a/resources/lang/en-US/validation.php +++ b/resources/lang/en-US/validation.php @@ -125,6 +125,8 @@ return [ 'symbols' => 'The :attribute field must contain at least one symbol.', 'uncompromised' => 'The given :attribute has appeared in a data leak. Please choose a different :attribute.', ], + 'percent' => 'The depreciation minimum must be between 0 and 100 when depreciation type is percentage.', + 'present' => 'The :attribute field must be present.', 'present_if' => 'The :attribute field must be present when :other is :value.', 'present_unless' => 'The :attribute field must be present unless :other is :value.', diff --git a/resources/views/depreciations/edit.blade.php b/resources/views/depreciations/edit.blade.php index a5376ea692..a281beebc2 100755 --- a/resources/views/depreciations/edit.blade.php +++ b/resources/views/depreciations/edit.blade.php @@ -28,9 +28,13 @@ -
- +
+ +
- {!! $errors->first('depreciation_min', '') !!} + {!! $errors->first('depreciation_min', '') !!}
@stop diff --git a/tests/Unit/DepreciationTest.php b/tests/Unit/DepreciationTest.php index 4dd8422276..e07edc6bef 100644 --- a/tests/Unit/DepreciationTest.php +++ b/tests/Unit/DepreciationTest.php @@ -1,10 +1,13 @@ assertEquals(5, $depreciation->models->count()); } + public function testDepreciationAmount() + { + $depreciation = Depreciation::factory()->create([ + 'depreciation_type' => 'amount', + 'depreciation_min' => 1000, + 'months'=> 36, + ]); + + $asset = Asset::factory() + ->laptopMbp() + ->create( + [ + 'category_id' => Category::factory()->assetLaptopCategory()->create(), + 'purchase_date' => now()->subDecade(), + 'purchase_cost' => 4000, + ]); + $asset->model->update([ + 'depreciation_id' => $depreciation->id, + ]); + + $asset->getLinearDepreciatedValue(); + + $this->assertEquals($depreciation->depreciation_min, $asset->getLinearDepreciatedValue()); + } + public function testDepreciationPercentage() + { + $depreciation = Depreciation::factory()->create([ + 'depreciation_type' => 'percent', + 'depreciation_min' => 50, + 'months'=> 36, + ]); + + $asset = Asset::factory() + ->laptopMbp() + ->create( + [ + 'category_id' => Category::factory()->assetLaptopCategory()->create(), + 'purchase_date' => now()->subDecade(), + 'purchase_cost' => 4000, + ]); + $asset->model->update([ + 'depreciation_id' => $depreciation->id, + ]); + + $asset->getLinearDepreciatedValue(); + + $this->assertEquals(2000, $asset->getLinearDepreciatedValue()); + } public function testADepreciationHasLicenses() {