From e9ee74cd0130ecc8a2a6f103eb8170e0ffb3bc8a Mon Sep 17 00:00:00 2001 From: Darko Gjorgjijoski Date: Fri, 3 Apr 2026 20:53:41 +0200 Subject: [PATCH] Add return types and typed parameters to remaining 10 models Complete the type modernization across all models. Adds Builder-typed $query parameters and return types to all scope methods, typed parameters on accessors, and PHPDoc on scopePaginateData/scopeApplyFilters. Models updated: Address, EstimateItem, Expense, ExpenseCategory, InvoiceItem, Item, Note, Tax, TaxType, Unit. 5 models needed no changes (Country, Currency, ImpersonationLog, Module, UserSetting) as they had no untyped public methods. --- app/Models/Address.php | 2 +- app/Models/EstimateItem.php | 3 ++- app/Models/Expense.php | 46 +++++++++++++++++++++------------- app/Models/ExpenseCategory.php | 23 +++++++++++------ app/Models/InvoiceItem.php | 9 ++++--- app/Models/Item.php | 27 +++++++++++++------- app/Models/Note.php | 9 ++++--- app/Models/Tax.php | 9 ++++--- app/Models/TaxType.php | 18 ++++++++----- app/Models/Unit.php | 16 ++++++++---- 10 files changed, 103 insertions(+), 59 deletions(-) diff --git a/app/Models/Address.php b/app/Models/Address.php index 9bc9b4ae..080466c4 100644 --- a/app/Models/Address.php +++ b/app/Models/Address.php @@ -16,7 +16,7 @@ class Address extends Model protected $guarded = ['id']; - public function getCountryNameAttribute() + public function getCountryNameAttribute(): ?string { $name = $this->country ? $this->country->name : null; diff --git a/app/Models/EstimateItem.php b/app/Models/EstimateItem.php index 2d9b9dfb..516e85d9 100644 --- a/app/Models/EstimateItem.php +++ b/app/Models/EstimateItem.php @@ -3,6 +3,7 @@ namespace App\Models; use App\Traits\HasCustomFieldsTrait; +use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; @@ -44,7 +45,7 @@ class EstimateItem extends Model return $this->hasMany(Tax::class); } - public function scopeWhereCompany($query, $company_id) + public function scopeWhereCompany(Builder $query, int $company_id): void { $query->where('company_id', $company_id); } diff --git a/app/Models/Expense.php b/app/Models/Expense.php index 54514b1b..b67c34e6 100644 --- a/app/Models/Expense.php +++ b/app/Models/Expense.php @@ -4,12 +4,16 @@ namespace App\Models; use App\Traits\HasCustomFieldsTrait; use Carbon\Carbon; +use Illuminate\Contracts\Pagination\LengthAwarePaginator; +use Illuminate\Database\Eloquent\Builder; +use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Support\Facades\DB; use Spatie\MediaLibrary\HasMedia; use Spatie\MediaLibrary\InteractsWithMedia; +use Spatie\MediaLibrary\MediaCollections\Models\Media; class Expense extends Model implements HasMedia { @@ -68,21 +72,21 @@ class Expense extends Model implements HasMedia return $this->belongsTo(User::class, 'creator_id'); } - public function getFormattedExpenseDateAttribute($value) + public function getFormattedExpenseDateAttribute(mixed $value): string { $dateFormat = CompanySetting::getSetting('carbon_date_format', $this->company_id); return Carbon::parse($this->expense_date)->translatedFormat($dateFormat); } - public function getFormattedCreatedAtAttribute($value) + public function getFormattedCreatedAtAttribute(mixed $value): string { $dateFormat = CompanySetting::getSetting('carbon_date_format', $this->company_id); return Carbon::parse($this->created_at)->translatedFormat($dateFormat); } - public function getReceiptUrlAttribute($value) + public function getReceiptUrlAttribute(mixed $value): ?array { $media = $this->getFirstMedia('receipts'); @@ -96,7 +100,7 @@ class Expense extends Model implements HasMedia return null; } - public function getReceiptAttribute($value) + public function getReceiptAttribute(mixed $value): ?string { $media = $this->getFirstMedia('receipts'); @@ -107,7 +111,7 @@ class Expense extends Model implements HasMedia return null; } - public function getReceiptMetaAttribute($value) + public function getReceiptMetaAttribute(mixed $value): ?Media { $media = $this->getFirstMedia('receipts'); @@ -118,7 +122,7 @@ class Expense extends Model implements HasMedia return null; } - public function scopeExpensesBetween($query, $start, $end) + public function scopeExpensesBetween(Builder $query, Carbon $start, Carbon $end): Builder { return $query->whereBetween( 'expenses.expense_date', @@ -126,7 +130,7 @@ class Expense extends Model implements HasMedia ); } - public function scopeWhereCategoryName($query, $search) + public function scopeWhereCategoryName(Builder $query, string $search): void { foreach (explode(' ', $search) as $term) { $query->whereHas('category', function ($query) use ($term) { @@ -135,22 +139,25 @@ class Expense extends Model implements HasMedia } } - public function scopeWhereNotes($query, $search) + public function scopeWhereNotes(Builder $query, string $search): void { $query->where('notes', 'LIKE', '%'.$search.'%'); } - public function scopeWhereCategory($query, $categoryId) + public function scopeWhereCategory(Builder $query, int $categoryId): Builder { return $query->where('expenses.expense_category_id', $categoryId); } - public function scopeWhereUser($query, $customer_id) + public function scopeWhereUser(Builder $query, int $customer_id): Builder { return $query->where('expenses.customer_id', $customer_id); } - public function scopeApplyFilters($query, array $filters) + /** + * Apply multiple filter conditions including category, customer, expense, date range, ordering, and search. + */ + public function scopeApplyFilters(Builder $query, array $filters): void { $filters = collect($filters); @@ -183,12 +190,12 @@ class Expense extends Model implements HasMedia } } - public function scopeWhereExpense($query, $expense_id) + public function scopeWhereExpense(Builder $query, int $expense_id): void { $query->orWhere('id', $expense_id); } - public function scopeWhereSearch($query, $search) + public function scopeWhereSearch(Builder $query, string $search): void { foreach (explode(' ', $search) as $term) { $query->whereHas('category', function ($query) use ($term) { @@ -198,22 +205,25 @@ class Expense extends Model implements HasMedia } } - public function scopeWhereOrder($query, $orderByField, $orderBy) + public function scopeWhereOrder(Builder $query, string $orderByField, string $orderBy): void { $query->orderBy($orderByField, $orderBy); } - public function scopeWhereCompany($query) + public function scopeWhereCompany(Builder $query): void { $query->where('expenses.company_id', request()->header('company')); } - public function scopeWhereCompanyId($query, $company) + public function scopeWhereCompanyId(Builder $query, int $company): void { $query->where('expenses.company_id', $company); } - public function scopePaginateData($query, $limit) + /** + * @return LengthAwarePaginator|Collection + */ + public function scopePaginateData(Builder $query, string $limit) { if ($limit == 'all') { return $query->get(); @@ -222,7 +232,7 @@ class Expense extends Model implements HasMedia return $query->paginate($limit); } - public function scopeExpensesAttributes($query) + public function scopeExpensesAttributes(Builder $query): void { $query->select( DB::raw(' diff --git a/app/Models/ExpenseCategory.php b/app/Models/ExpenseCategory.php index 3b02fe4c..bf86c2fa 100644 --- a/app/Models/ExpenseCategory.php +++ b/app/Models/ExpenseCategory.php @@ -3,6 +3,9 @@ namespace App\Models; use Carbon\Carbon; +use Illuminate\Contracts\Pagination\LengthAwarePaginator; +use Illuminate\Database\Eloquent\Builder; +use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; @@ -31,34 +34,37 @@ class ExpenseCategory extends Model return $this->belongsTo(Company::class); } - public function getFormattedCreatedAtAttribute($value) + public function getFormattedCreatedAtAttribute(mixed $value): string { $dateFormat = CompanySetting::getSetting('carbon_date_format', $this->company_id); return Carbon::parse($this->created_at)->format($dateFormat); } - public function getAmountAttribute() + public function getAmountAttribute(): float { return $this->expenses()->sum('amount'); } - public function scopeWhereCompany($query) + public function scopeWhereCompany(Builder $query): void { $query->where('company_id', request()->header('company')); } - public function scopeWhereCategory($query, $category_id) + public function scopeWhereCategory(Builder $query, int $category_id): void { $query->orWhere('id', $category_id); } - public function scopeWhereSearch($query, $search) + public function scopeWhereSearch(Builder $query, string $search): void { $query->where('name', 'LIKE', '%'.$search.'%'); } - public function scopeApplyFilters($query, array $filters) + /** + * Apply multiple filter conditions including category, company, and search. + */ + public function scopeApplyFilters(Builder $query, array $filters): void { $filters = collect($filters); @@ -75,7 +81,10 @@ class ExpenseCategory extends Model } } - public function scopePaginateData($query, $limit) + /** + * @return LengthAwarePaginator|Collection + */ + public function scopePaginateData(Builder $query, string $limit) { if ($limit == 'all') { return $query->get(); diff --git a/app/Models/InvoiceItem.php b/app/Models/InvoiceItem.php index b4ec3a9d..39755414 100644 --- a/app/Models/InvoiceItem.php +++ b/app/Models/InvoiceItem.php @@ -4,6 +4,7 @@ namespace App\Models; use App\Traits\HasCustomFieldsTrait; use Carbon\Carbon; +use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; @@ -51,12 +52,12 @@ class InvoiceItem extends Model return $this->belongsTo(RecurringInvoice::class); } - public function scopeWhereCompany($query, $company_id) + public function scopeWhereCompany(Builder $query, int $company_id): void { $query->where('company_id', $company_id); } - public function scopeInvoicesBetween($query, $start, $end) + public function scopeInvoicesBetween(Builder $query, Carbon $start, Carbon $end): void { $query->whereHas('invoice', function ($query) use ($start, $end) { $query->whereBetween( @@ -66,7 +67,7 @@ class InvoiceItem extends Model }); } - public function scopeApplyInvoiceFilters($query, array $filters) + public function scopeApplyInvoiceFilters(Builder $query, array $filters): void { $filters = collect($filters); @@ -77,7 +78,7 @@ class InvoiceItem extends Model } } - public function scopeItemAttributes($query) + public function scopeItemAttributes(Builder $query): void { $query->select( DB::raw('sum(quantity) as total_quantity, sum(base_total) as total_amount, invoice_items.name') diff --git a/app/Models/Item.php b/app/Models/Item.php index 7ab89e02..fc90d65c 100644 --- a/app/Models/Item.php +++ b/app/Models/Item.php @@ -3,6 +3,9 @@ namespace App\Models; use Carbon\Carbon; +use Illuminate\Contracts\Pagination\LengthAwarePaginator; +use Illuminate\Database\Eloquent\Builder; +use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; @@ -45,32 +48,35 @@ class Item extends Model return $this->belongsTo(Currency::class); } - public function scopeWhereSearch($query, $search) + public function scopeWhereSearch(Builder $query, string $search): Builder { return $query->where('items.name', 'LIKE', '%'.$search.'%'); } - public function scopeWherePrice($query, $price) + public function scopeWherePrice(Builder $query, int $price): Builder { return $query->where('items.price', $price); } - public function scopeWhereUnit($query, $unit_id) + public function scopeWhereUnit(Builder $query, int $unit_id): Builder { return $query->where('items.unit_id', $unit_id); } - public function scopeWhereOrder($query, $orderByField, $orderBy) + public function scopeWhereOrder(Builder $query, string $orderByField, string $orderBy): void { $query->orderBy($orderByField, $orderBy); } - public function scopeWhereItem($query, $item_id) + public function scopeWhereItem(Builder $query, int $item_id): void { $query->orWhere('id', $item_id); } - public function scopeApplyFilters($query, array $filters) + /** + * Apply multiple filter conditions including search, price, unit, item, and ordering. + */ + public function scopeApplyFilters(Builder $query, array $filters): void { $filters = collect($filters); @@ -97,7 +103,10 @@ class Item extends Model } } - public function scopePaginateData($query, $limit) + /** + * @return LengthAwarePaginator|Collection + */ + public function scopePaginateData(Builder $query, string $limit) { if ($limit == 'all') { return $query->get(); @@ -106,7 +115,7 @@ class Item extends Model return $query->paginate($limit); } - public function getFormattedCreatedAtAttribute($value) + public function getFormattedCreatedAtAttribute(mixed $value): string { $dateFormat = CompanySetting::getSetting('carbon_date_format', request()->header('company')); @@ -120,7 +129,7 @@ class Item extends Model ->where('estimate_item_id', null); } - public function scopeWhereCompany($query) + public function scopeWhereCompany(Builder $query): void { $query->where('items.company_id', request()->header('company')); } diff --git a/app/Models/Note.php b/app/Models/Note.php index 32cdff52..7ede3c96 100644 --- a/app/Models/Note.php +++ b/app/Models/Note.php @@ -2,6 +2,7 @@ namespace App\Models; +use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; @@ -17,7 +18,7 @@ class Note extends Model return $this->belongsTo(Company::class); } - public function scopeApplyFilters($query, array $filters) + public function scopeApplyFilters(Builder $query, array $filters): void { $filters = collect($filters); @@ -30,17 +31,17 @@ class Note extends Model } } - public function scopeWhereSearch($query, $search) + public function scopeWhereSearch(Builder $query, string $search): void { $query->where('name', 'LIKE', '%'.$search.'%'); } - public function scopeWhereType($query, $type) + public function scopeWhereType(Builder $query, string $type): Builder { return $query->where('type', $type); } - public function scopeWhereCompany($query) + public function scopeWhereCompany(Builder $query): void { $query->where('notes.company_id', request()->header('company')); } diff --git a/app/Models/Tax.php b/app/Models/Tax.php index ae5682c6..f56d37d0 100644 --- a/app/Models/Tax.php +++ b/app/Models/Tax.php @@ -3,6 +3,7 @@ namespace App\Models; use Carbon\Carbon; +use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; @@ -65,19 +66,19 @@ class Tax extends Model return $this->belongsTo(Item::class); } - public function scopeWhereCompany($query, $company_id) + public function scopeWhereCompany(Builder $query, int $company_id): void { $query->where('company_id', $company_id); } - public function scopeTaxAttributes($query) + public function scopeTaxAttributes(Builder $query): void { $query->select( DB::raw('sum(base_amount) as total_tax_amount, tax_type_id') )->groupBy('tax_type_id'); } - public function scopeInvoicesBetween($query, $start, $end) + public function scopeInvoicesBetween(Builder $query, Carbon $start, Carbon $end): void { $query->whereHas('invoice', function ($query) use ($start, $end) { $query->where('paid_status', Invoice::STATUS_PAID) @@ -95,7 +96,7 @@ class Tax extends Model }); } - public function scopeWhereInvoicesFilters($query, array $filters) + public function scopeWhereInvoicesFilters(Builder $query, array $filters): void { $filters = collect($filters); diff --git a/app/Models/TaxType.php b/app/Models/TaxType.php index 85480f0e..961ccee1 100644 --- a/app/Models/TaxType.php +++ b/app/Models/TaxType.php @@ -2,6 +2,9 @@ namespace App\Models; +use Illuminate\Contracts\Pagination\LengthAwarePaginator; +use Illuminate\Database\Eloquent\Builder; +use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; @@ -38,17 +41,17 @@ class TaxType extends Model return $this->belongsTo(Company::class); } - public function scopeWhereCompany($query) + public function scopeWhereCompany(Builder $query): void { $query->where('company_id', request()->header('company')); } - public function scopeWhereTaxType($query, $tax_type_id) + public function scopeWhereTaxType(Builder $query, int $tax_type_id): void { $query->orWhere('id', $tax_type_id); } - public function scopeApplyFilters($query, array $filters) + public function scopeApplyFilters(Builder $query, array $filters): void { $filters = collect($filters); @@ -71,17 +74,20 @@ class TaxType extends Model } } - public function scopeWhereOrder($query, $orderByField, $orderBy) + public function scopeWhereOrder(Builder $query, string $orderByField, string $orderBy): void { $query->orderBy($orderByField, $orderBy); } - public function scopeWhereSearch($query, $search) + public function scopeWhereSearch(Builder $query, string $search): void { $query->where('name', 'LIKE', '%'.$search.'%'); } - public function scopePaginateData($query, $limit) + /** + * @return Collection|LengthAwarePaginator + */ + public function scopePaginateData(Builder $query, string $limit) { if ($limit == 'all') { return $query->get(); diff --git a/app/Models/Unit.php b/app/Models/Unit.php index 5fe010ed..f10cee63 100644 --- a/app/Models/Unit.php +++ b/app/Models/Unit.php @@ -2,6 +2,9 @@ namespace App\Models; +use Illuminate\Contracts\Pagination\LengthAwarePaginator; +use Illuminate\Database\Eloquent\Builder; +use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; @@ -23,22 +26,22 @@ class Unit extends Model return $this->belongsTo(Company::class); } - public function scopeWhereCompany($query) + public function scopeWhereCompany(Builder $query): void { $query->where('company_id', request()->header('company')); } - public function scopeWhereUnit($query, $unit_id) + public function scopeWhereUnit(Builder $query, int $unit_id): void { $query->orWhere('id', $unit_id); } - public function scopeWhereSearch($query, $search) + public function scopeWhereSearch(Builder $query, string $search): Builder { return $query->where('name', 'LIKE', '%'.$search.'%'); } - public function scopeApplyFilters($query, array $filters) + public function scopeApplyFilters(Builder $query, array $filters): Builder { $filters = collect($filters); @@ -57,7 +60,10 @@ class Unit extends Model return $query; } - public function scopePaginateData($query, $limit) + /** + * @return Collection|LengthAwarePaginator + */ + public function scopePaginateData(Builder $query, string $limit) { if ($limit == 'all') { return $query->get();