chore(money,taxation): remove legacy-era money and taxation sources

This commit is contained in:
Darko Gjorgjijoski
2026-08-20 20:54:20 +02:00
parent d8a96a3fb8
commit 398863e437
19 changed files with 0 additions and 1337 deletions
@@ -1,23 +0,0 @@
<?php
namespace App\Domains\Money\Http\Controllers;
use App\Domains\Money\Application\CurrencyService;
use App\Domains\Money\Http\Resources\CurrencyResource;
use App\Platform\Http\Controller;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
class CurrenciesController extends Controller
{
public function __construct(
private readonly CurrencyService $currencyService,
) {}
public function __invoke(Request $request): AnonymousResourceCollection
{
$currencies = $this->currencyService->getAllWithCommonFirst();
return CurrencyResource::collection($currencies);
}
}
@@ -1,274 +0,0 @@
<?php
namespace App\Domains\Money\Http\Controllers;
use App\Domains\Accounts\Models\CompanySetting;
use App\Domains\Money\Application\ExchangeRateProviderService;
use App\Domains\Money\Contracts\ExchangeRateBackfill;
use App\Domains\Money\ExchangeRates\ExchangeRateException;
use App\Domains\Money\Http\Requests\BulkExchangeRateRequest;
use App\Domains\Money\Http\Requests\ExchangeRateProviderRequest;
use App\Domains\Money\Http\Resources\ExchangeRateProviderResource;
use App\Domains\Money\Models\Currency;
use App\Domains\Money\Models\ExchangeRateLog;
use App\Domains\Money\Models\ExchangeRateProvider;
use App\Platform\Http\Controller;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Arr;
class ExchangeRateProviderController extends Controller
{
public function __construct(
private readonly ExchangeRateProviderService $exchangeRateProviderService,
private readonly ExchangeRateBackfill $exchangeRateBackfill,
) {}
/**
* Display a listing of the resource.
*
* @return Response
*/
public function index(Request $request)
{
$this->authorize('viewAny', ExchangeRateProvider::class);
$limit = $request->has('limit') ? $request->limit : 5;
$exchangeRateProviders = ExchangeRateProvider::whereCompany()->paginate($limit);
return ExchangeRateProviderResource::collection($exchangeRateProviders);
}
/**
* Store a newly created resource in storage.
*
* @param Request $request
* @return Response
*/
public function store(ExchangeRateProviderRequest $request)
{
$this->authorize('create', ExchangeRateProvider::class);
$payload = $request->getExchangeRateProviderPayload();
$query = $this->exchangeRateProviderService->checkActiveCurrencies($payload['currencies'] ?? []);
if (count($query) !== 0) {
return respondJson('currency_used', 'Currency used.');
}
try {
$this->exchangeRateProviderService->validateProvider($payload);
$exchangeRateProvider = $this->exchangeRateProviderService->create($payload);
return new ExchangeRateProviderResource($exchangeRateProvider);
} catch (ExchangeRateException $exception) {
return respondJson($exception->errorKey, $exception->getMessage());
}
}
/**
* Display the specified resource.
*
* @return Response
*/
public function show(ExchangeRateProvider $exchangeRateProvider)
{
$this->authorize('view', $exchangeRateProvider);
return new ExchangeRateProviderResource($exchangeRateProvider);
}
/**
* Update the specified resource in storage.
*
* @param Request $request
* @return Response
*/
public function update(ExchangeRateProviderRequest $request, ExchangeRateProvider $exchangeRateProvider)
{
$this->authorize('update', $exchangeRateProvider);
$payload = $request->getExchangeRateProviderPayload();
$query = $this->exchangeRateProviderService->checkUpdateActiveCurrencies(
$exchangeRateProvider,
$payload['currencies'] ?? [],
);
if (count($query) !== 0) {
return respondJson('currency_used', 'Currency used.');
}
try {
$this->exchangeRateProviderService->validateProvider($payload);
$this->exchangeRateProviderService->update($exchangeRateProvider, $payload);
return new ExchangeRateProviderResource($exchangeRateProvider);
} catch (ExchangeRateException $exception) {
return respondJson($exception->errorKey, $exception->getMessage());
}
}
/**
* Remove the specified resource from storage.
*
* @return Response
*/
public function destroy(ExchangeRateProvider $exchangeRateProvider)
{
$this->authorize('delete', $exchangeRateProvider);
if ($exchangeRateProvider->active == true) {
return respondJson('provider_active', 'Provider Active.');
}
$exchangeRateProvider->delete();
return response()->json([
'success' => true,
]);
}
public function activeProvider(Request $request, Currency $currency)
{
$query = ExchangeRateProvider::whereCompany()->whereJsonContains('currencies', $currency->code)
->where('active', true)
->get();
if (count($query) !== 0) {
return response()->json([
'success' => true,
'message' => 'provider_active',
], 200);
}
return response()->json([
'error' => 'no_active_provider',
], 200);
}
public function getRate(Request $request, Currency $currency)
{
$settings = CompanySetting::getSettings(['currency'], $request->header('company'));
$baseCurrency = Currency::findOrFail($settings['currency']);
$query = ExchangeRateProvider::whereJsonContains('currencies', $currency->code)
->where('active', true)
->get()
->toArray();
$exchangeRate = ExchangeRateLog::where('base_currency_id', $currency->id)
->where('currency_id', $baseCurrency->id)
->orderBy('created_at', 'desc')
->value('exchange_rate');
if ($query) {
$filter = Arr::only($query[0], ['key', 'driver', 'driver_config']);
try {
$exchangeRate = $this->exchangeRateProviderService->getExchangeRate(
$filter['driver'],
$filter['key'],
$filter['driver_config'] ?? [],
$currency->code,
$baseCurrency->code,
);
return response()->json(['exchangeRate' => $exchangeRate]);
} catch (ExchangeRateException) {
// Fall back to the latest stored rate below, matching the
// existing API behavior when a live provider is unavailable.
}
}
if ($exchangeRate) {
return response()->json([
'exchangeRate' => [$exchangeRate],
], 200);
}
return response()->json([
'error' => 'no_exchange_rate_available',
], 200);
}
public function supportedCurrencies(Request $request)
{
$this->authorize('viewAny', ExchangeRateProvider::class);
try {
$currencies = $this->exchangeRateProviderService->getSupportedCurrencies(
$request->driver,
$request->key,
$request->driver_config ?? [],
);
return response()->json(['supportedCurrencies' => $currencies]);
} catch (ExchangeRateException $exception) {
return respondJson($exception->errorKey, $exception->getMessage());
}
}
public function usedCurrencies(Request $request)
{
$this->authorize('viewAny', ExchangeRateProvider::class);
$providerId = $request->provider_id;
$activeExchangeRateProviders = ExchangeRateProvider::where('active', true)
->whereCompany()
->when($providerId, function ($query) use ($providerId) {
return $query->where('id', '<>', $providerId);
})
->pluck('currencies');
$activeExchangeRateProvider = [];
foreach ($activeExchangeRateProviders as $data) {
if (is_array($data)) {
for ($limit = 0; $limit < count($data); $limit++) {
$activeExchangeRateProvider[] = $data[$limit];
}
}
}
$allExchangeRateProviders = ExchangeRateProvider::whereCompany()->pluck('currencies');
$allExchangeRateProvider = [];
foreach ($allExchangeRateProviders as $data) {
if (is_array($data)) {
for ($limit = 0; $limit < count($data); $limit++) {
$allExchangeRateProvider[] = $data[$limit];
}
}
}
return response()->json([
'allUsedCurrencies' => $allExchangeRateProvider ? $allExchangeRateProvider : [],
'activeUsedCurrencies' => $activeExchangeRateProvider ? $activeExchangeRateProvider : [],
]);
}
public function usedCurrenciesWithoutRate(Request $request)
{
return response()->json([
'currencies' => Currency::whereIn(
'id',
$this->exchangeRateBackfill->currencyIdsMissingRates(),
)->get(),
]);
}
public function bulkUpdate(BulkExchangeRateRequest $request)
{
if ($this->exchangeRateBackfill->apply(
(int) $request->header('company'),
$request->validated('currencies'),
)) {
return response()->json([
'success' => true,
]);
}
return response()->json([
'error' => false,
]);
}
}
@@ -1,35 +0,0 @@
<?php
namespace App\Domains\Money\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class BulkExchangeRateRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*/
public function rules(): array
{
return [
'currencies' => [
'required',
],
'currencies.*.id' => [
'required',
'numeric',
],
'currencies.*.exchange_rate' => [
'required',
],
];
}
}
@@ -1,64 +0,0 @@
<?php
namespace App\Domains\Money\Http\Requests;
use App\Rules\PublicHttpUrl;
use Illuminate\Foundation\Http\FormRequest;
class ExchangeRateProviderRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*/
public function rules(): array
{
$rules = [
'driver' => [
'required',
],
'key' => [
'required',
],
'currencies' => [
'nullable',
],
'currencies.*' => [
'nullable',
],
'driver_config' => [
'nullable',
],
// Only the CurrencyConverter "DEDICATED" plan reads a custom URL from
// driver_config; guard it against SSRF (private/reserved targets).
'driver_config.url' => [
'nullable',
'string',
'url',
new PublicHttpUrl,
],
'active' => [
'nullable',
'boolean',
],
];
return $rules;
}
public function getExchangeRateProviderPayload()
{
return collect($this->validated())
->merge([
'company_id' => $this->header('company'),
])
->toArray();
}
}
@@ -1,29 +0,0 @@
<?php
namespace App\Domains\Money\Http\Resources;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
class CurrencyResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param Request $request
*/
public function toArray($request): array
{
return [
'id' => $this->id,
'name' => $this->name,
'code' => $this->code,
'symbol' => $this->symbol,
'precision' => $this->precision,
'thousand_separator' => $this->thousand_separator,
'decimal_separator' => $this->decimal_separator,
'swap_currency_symbol' => $this->swap_currency_symbol,
'exchange_rate' => $this->exchange_rate,
];
}
}
@@ -1,29 +0,0 @@
<?php
namespace App\Domains\Money\Http\Resources\CustomerPortal;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
class CurrencyResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param Request $request
*/
public function toArray($request): array
{
return [
'id' => $this->id,
'name' => $this->name,
'code' => $this->code,
'symbol' => $this->symbol,
'precision' => $this->precision,
'thousand_separator' => $this->thousand_separator,
'decimal_separator' => $this->decimal_separator,
'swap_currency_symbol' => $this->swap_currency_symbol,
'exchange_rate' => $this->exchange_rate,
];
}
}
@@ -1,31 +0,0 @@
<?php
namespace App\Domains\Money\Http\Resources;
use App\Domains\Accounts\Http\Resources\CompanyResource;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
class ExchangeRateProviderResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param Request $request
*/
public function toArray($request): array
{
return [
'id' => $this->id,
'key' => $this->key,
'driver' => $this->driver,
'currencies' => $this->currencies,
'driver_config' => $this->driver_config,
'company_id' => $this->company_id,
'active' => $this->active,
'company' => $this->when($this->company()->exists(), function () {
return new CompanyResource($this->company);
}),
];
}
}
-22
View File
@@ -1,22 +0,0 @@
<?php
namespace App\Domains\Money\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Currency extends Model
{
protected $table = 'currencies';
use HasFactory;
public const COMMON_CURRENCY_CODES = [
'USD', 'EUR', 'GBP', 'JPY', 'CAD',
'AUD', 'CHF', 'CNY', 'INR', 'BRL',
];
protected $guarded = [
'id',
];
}
@@ -1,53 +0,0 @@
<?php
namespace App\Domains\Money\Models;
use App\Domains\Accounts\Models\Company;
use App\Domains\Accounts\Models\CompanySetting;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class ExchangeRateLog extends Model
{
protected $table = 'exchange_rate_logs';
use HasFactory;
protected $guarded = [
'id',
];
protected function casts(): array
{
return [
'exchange_rate' => 'float',
];
}
public function currency(): BelongsTo
{
return $this->belongsTo(Currency::class);
}
public function company(): BelongsTo
{
return $this->belongsTo(Company::class);
}
/**
* Create an exchange rate log entry from a document model (invoice, estimate, etc.)
* using its exchange rate, currency, and the company's default currency setting.
*/
public static function addExchangeRateLog(mixed $model): self
{
$data = [
'exchange_rate' => $model->exchange_rate,
'company_id' => $model->company_id,
'base_currency_id' => $model->currency_id,
'currency_id' => CompanySetting::getSetting('currency', $model->company_id),
];
return self::create($data);
}
}
@@ -1,48 +0,0 @@
<?php
namespace App\Domains\Money\Models;
use App\Domains\Accounts\Models\Company;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class ExchangeRateProvider extends Model
{
protected $table = 'exchange_rate_providers';
use HasFactory;
protected $guarded = [
'id',
];
protected function casts(): array
{
return [
'currencies' => 'array',
'driver_config' => 'array',
'active' => 'boolean',
];
}
public function company(): BelongsTo
{
return $this->belongsTo(Company::class);
}
public function setCurrenciesAttribute($value)
{
$this->attributes['currencies'] = json_encode($value);
}
public function setDriverConfigAttribute($value)
{
$this->attributes['driver_config'] = json_encode($value);
}
public function scopeWhereCompany($query)
{
$query->where('exchange_rate_providers.company_id', request()->header('company'));
}
}
@@ -1,104 +0,0 @@
<?php
namespace App\Domains\Money\Policies;
use App\Domains\Accounts\Models\User;
use App\Domains\Money\Models\ExchangeRateProvider;
use Illuminate\Auth\Access\HandlesAuthorization;
use Illuminate\Auth\Access\Response;
use Silber\Bouncer\BouncerFacade;
class ExchangeRateProviderPolicy
{
use HandlesAuthorization;
/**
* Determine whether the user can view any models.
*
* @return Response|bool
*/
public function viewAny(User $user): bool
{
if (BouncerFacade::can('view-exchange-rate-provider', ExchangeRateProvider::class)) {
return true;
}
return false;
}
/**
* Determine whether the user can view the model.
*
* @return Response|bool
*/
public function view(User $user, ExchangeRateProvider $exchangeRateProvider): bool
{
if (BouncerFacade::can('view-exchange-rate-provider', $exchangeRateProvider) && $user->hasCompany($exchangeRateProvider->company_id)) {
return true;
}
return false;
}
/**
* Determine whether the user can create models.
*
* @return Response|bool
*/
public function create(User $user): bool
{
if (BouncerFacade::can('create-exchange-rate-provider', ExchangeRateProvider::class)) {
return true;
}
return false;
}
/**
* Determine whether the user can update the model.
*
* @return Response|bool
*/
public function update(User $user, ExchangeRateProvider $exchangeRateProvider): bool
{
if (BouncerFacade::can('edit-exchange-rate-provider', $exchangeRateProvider) && $user->hasCompany($exchangeRateProvider->company_id)) {
return true;
}
return false;
}
/**
* Determine whether the user can delete the model.
*
* @return Response|bool
*/
public function delete(User $user, ExchangeRateProvider $exchangeRateProvider): bool
{
if (BouncerFacade::can('delete-exchange-rate-provider', $exchangeRateProvider) && $user->hasCompany($exchangeRateProvider->company_id)) {
return true;
}
return false;
}
/**
* Determine whether the user can restore the model.
*
* @return Response|bool
*/
public function restore(User $user, ExchangeRateProvider $exchangeRateProvider): bool
{
//
}
/**
* Determine whether the user can permanently delete the model.
*
* @return Response|bool
*/
public function forceDelete(User $user, ExchangeRateProvider $exchangeRateProvider): bool
{
//
}
}
@@ -1,95 +0,0 @@
<?php
namespace App\Domains\Taxation\Http\Controllers;
use App\Domains\Taxation\Http\Requests\TaxTypeRequest;
use App\Domains\Taxation\Http\Resources\TaxTypeResource;
use App\Domains\Taxation\Models\TaxType;
use App\Platform\Http\Controller;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
class TaxTypesController extends Controller
{
/**
* Display a listing of the resource.
*
* @return Response
*/
public function index(Request $request)
{
$this->authorize('viewAny', TaxType::class);
$limit = $request->has('limit') ? $request->limit : 5;
$taxTypes = TaxType::applyFilters($request->all())
->where('type', TaxType::TYPE_GENERAL)
->whereCompany()
->latest()
->paginateData($limit);
return TaxTypeResource::collection($taxTypes);
}
/**
* Store a newly created resource in storage.
*
* @param Request $request
* @return Response
*/
public function store(TaxTypeRequest $request)
{
$this->authorize('create', TaxType::class);
$taxType = TaxType::create($request->getTaxTypePayload());
return new TaxTypeResource($taxType);
}
/**
* Display the specified resource.
*
* @return Response
*/
public function show(TaxType $taxType)
{
$this->authorize('view', $taxType);
return new TaxTypeResource($taxType);
}
/**
* Update the specified resource in storage.
*
* @param Request $request
* @return Response
*/
public function update(TaxTypeRequest $request, TaxType $taxType)
{
$this->authorize('update', $taxType);
$taxType->update($request->getTaxTypePayload());
return new TaxTypeResource($taxType);
}
/**
* Remove the specified resource from storage.
*
* @return Response
*/
public function destroy(TaxType $taxType)
{
$this->authorize('delete', $taxType);
if ($taxType->taxes() && $taxType->taxes()->count() > 0) {
return respondJson('taxes_attached', 'Taxes Attached.');
}
$taxType->delete();
return response()->json([
'success' => true,
]);
}
}
@@ -1,42 +0,0 @@
<?php
namespace App\Domains\Taxation\Http\Resources\CustomerPortal;
use App\Domains\Money\Http\Resources\CustomerPortal\CurrencyResource;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
class TaxResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param Request $request
*/
public function toArray($request): array
{
return [
'id' => $this->id,
'tax_type_id' => $this->tax_type_id,
'invoice_id' => $this->invoice_id,
'estimate_id' => $this->estimate_id,
'invoice_item_id' => $this->invoice_item_id,
'estimate_item_id' => $this->estimate_item_id,
'item_id' => $this->item_id,
'company_id' => $this->company_id,
'name' => $this->name,
'amount' => $this->amount,
'percent' => $this->percent,
'compound_tax' => $this->compound_tax,
'base_amount' => $this->base_amount,
'currency_id' => $this->currency_id,
'recurring_invoice_id' => $this->recurring_invoice_id,
'tax_type' => $this->when($this->taxType()->exists(), function () {
return new TaxTypeResource($this->taxType);
}),
'currency' => $this->when($this->currency()->exists(), function () {
return new CurrencyResource($this->currency);
}),
];
}
}
@@ -1,32 +0,0 @@
<?php
namespace App\Domains\Taxation\Http\Resources\CustomerPortal;
use App\Domains\Accounts\Http\Resources\CustomerPortal\CompanyResource;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
class TaxTypeResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param Request $request
*/
public function toArray($request): array
{
return [
'id' => $this->id,
'name' => $this->name,
'percent' => $this->percent,
'transaction_type' => $this->transaction_type,
'compound_tax' => $this->compound_tax,
'collective_tax' => $this->collective_tax,
'description' => $this->description,
'company_id' => $this->company_id,
'company' => $this->when($this->company()->exists(), function () {
return new CompanyResource($this->company);
}),
];
}
}
@@ -1,46 +0,0 @@
<?php
namespace App\Domains\Taxation\Http\Resources;
use App\Domains\Money\Http\Resources\CurrencyResource;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
class TaxResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param Request $request
*/
public function toArray($request): array
{
return [
'id' => $this->id,
'tax_type_id' => $this->tax_type_id,
'invoice_id' => $this->invoice_id,
'estimate_id' => $this->estimate_id,
'invoice_item_id' => $this->invoice_item_id,
'estimate_item_id' => $this->estimate_item_id,
'expense_id' => $this->expense_id,
'item_id' => $this->item_id,
'company_id' => $this->company_id,
'name' => $this->name,
'amount' => $this->amount,
'percent' => $this->percent,
'calculation_type' => $this->calculation_type,
'fixed_amount' => $this->fixed_amount,
'compound_tax' => $this->compound_tax,
'base_amount' => $this->base_amount,
'currency_id' => $this->currency_id,
'type' => $this->taxType->type,
'recurring_invoice_id' => $this->recurring_invoice_id,
'tax_type' => $this->when($this->taxType()->exists(), function () {
return new TaxTypeResource($this->taxType);
}),
'currency' => $this->when($this->currency()->exists(), function () {
return new CurrencyResource($this->currency);
}),
];
}
}
@@ -1,35 +0,0 @@
<?php
namespace App\Domains\Taxation\Http\Resources;
use App\Domains\Accounts\Http\Resources\CompanyResource;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
class TaxTypeResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param Request $request
*/
public function toArray($request): array
{
return [
'id' => $this->id,
'name' => $this->name,
'percent' => $this->percent,
'fixed_amount' => $this->fixed_amount,
'calculation_type' => $this->calculation_type,
'type' => $this->type,
'transaction_type' => $this->transaction_type,
'compound_tax' => $this->compound_tax,
'collective_tax' => $this->collective_tax,
'description' => $this->description,
'company_id' => $this->company_id,
'company' => $this->when($this->company()->exists(), function () {
return new CompanyResource($this->company);
}),
];
}
}
-149
View File
@@ -1,149 +0,0 @@
<?php
namespace App\Domains\Taxation\Models;
use App\Domains\Catalog\Models\Item;
use App\Domains\Money\Models\Currency;
use App\Domains\Purchases\Models\Expense;
use App\Domains\Sales\Models\Estimate;
use App\Domains\Sales\Models\EstimateItem;
use App\Domains\Sales\Models\Invoice;
use App\Domains\Sales\Models\InvoiceItem;
use App\Domains\Sales\Models\RecurringInvoice;
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;
use Illuminate\Support\Facades\DB;
class Tax extends Model
{
protected $table = 'taxes';
use HasFactory;
protected $guarded = [
'id',
];
protected function casts(): array
{
return [
'amount' => 'integer',
'percent' => 'float',
'fixed_amount' => 'integer',
'compound_tax' => 'boolean',
];
}
public function taxType(): BelongsTo
{
return $this->belongsTo(TaxType::class);
}
public function invoice(): BelongsTo
{
return $this->belongsTo(Invoice::class);
}
public function recurringInvoice(): BelongsTo
{
return $this->belongsTo(RecurringInvoice::class);
}
public function estimate(): BelongsTo
{
return $this->belongsTo(Estimate::class);
}
public function currency(): BelongsTo
{
return $this->belongsTo(Currency::class);
}
public function invoiceItem(): BelongsTo
{
return $this->belongsTo(InvoiceItem::class);
}
public function expense(): BelongsTo
{
return $this->belongsTo(Expense::class);
}
public function estimateItem(): BelongsTo
{
return $this->belongsTo(EstimateItem::class);
}
public function item(): BelongsTo
{
return $this->belongsTo(Item::class);
}
public function scopeWhereCompany(Builder $query, int $company_id): void
{
$query->where('company_id', $company_id);
}
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(Builder $query, Carbon $start, Carbon $end): void
{
$query->where(function (Builder $query) use ($start, $end) {
$query->whereHas('invoice', function (Builder $query) use ($start, $end) {
$query->where('paid_status', Invoice::STATUS_PAID)
->whereBetween(
'invoice_date',
[$start->format('Y-m-d'), $end->format('Y-m-d')]
);
})->orWhereHas('invoiceItem.invoice', function (Builder $query) use ($start, $end) {
$query->where('paid_status', Invoice::STATUS_PAID)
->whereBetween(
'invoice_date',
[$start->format('Y-m-d'), $end->format('Y-m-d')]
);
});
});
}
public function scopeWhereInvoicesFilters(Builder $query, array $filters): void
{
$filters = collect($filters);
if ($filters->get('from_date') && $filters->get('to_date')) {
$start = Carbon::createFromFormat('Y-m-d', $filters->get('from_date'));
$end = Carbon::createFromFormat('Y-m-d', $filters->get('to_date'));
$query->invoicesBetween($start, $end);
}
}
public function scopeExpensesBetween(Builder $query, Carbon $start, Carbon $end): void
{
$query->whereHas('expense', function (Builder $query) use ($start, $end) {
$query->whereBetween(
'expense_date',
[$start->format('Y-m-d'), $end->format('Y-m-d')]
);
});
}
public function scopeWhereExpensesFilters(Builder $query, array $filters): void
{
$filters = collect($filters);
if ($filters->get('from_date') && $filters->get('to_date')) {
$start = Carbon::createFromFormat('Y-m-d', $filters->get('from_date'));
$end = Carbon::createFromFormat('Y-m-d', $filters->get('to_date'));
$query->expensesBetween($start, $end);
}
}
}
-115
View File
@@ -1,115 +0,0 @@
<?php
namespace App\Domains\Taxation\Models;
use App\Domains\Accounts\Models\Company;
use App\Support\SafeOrderBy;
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\Database\Eloquent\Relations\HasMany;
class TaxType extends Model
{
protected $table = 'tax_types';
use HasFactory;
protected $guarded = [
'id',
];
protected function casts(): array
{
return [
'percent' => 'float',
'fixed_amount' => 'integer',
'compound_tax' => 'boolean',
];
}
public const TYPE_GENERAL = 'GENERAL';
public const TYPE_MODULE = 'MODULE';
public const TRANSACTION_TYPE_SALES = 'sales';
public const TRANSACTION_TYPE_PURCHASES = 'purchases';
public function taxes(): HasMany
{
return $this->hasMany(Tax::class);
}
public function company(): BelongsTo
{
return $this->belongsTo(Company::class);
}
public function scopeWhereCompany(Builder $query): void
{
$query->where('company_id', request()->header('company'));
}
public function scopeWhereTaxType(Builder $query, int $tax_type_id): void
{
$query->orWhere('id', $tax_type_id);
}
public function scopeWhereTransactionType(Builder $query, string $transaction_type): void
{
$query->where('transaction_type', $transaction_type);
}
public function scopeApplyFilters(Builder $query, array $filters): void
{
$filters = collect($filters);
if ($filters->get('tax_type_id')) {
$query->whereTaxType($filters->get('tax_type_id'));
}
if ($filters->get('company_id')) {
$query->whereCompany($filters->get('company_id'));
}
if ($filters->get('transaction_type')) {
$query->whereTransactionType($filters->get('transaction_type'));
}
if ($filters->get('search')) {
$query->whereSearch($filters->get('search'));
}
if ($filters->get('orderByField') || $filters->get('orderBy')) {
$field = $filters->get('orderByField') ? $filters->get('orderByField') : 'payment_number';
$orderBy = $filters->get('orderBy') ? $filters->get('orderBy') : 'asc';
$query->whereOrder($field, $orderBy);
}
}
public function scopeWhereOrder(Builder $query, string $orderByField, string $orderBy): void
{
SafeOrderBy::apply($query, $orderByField, $orderBy);
}
public function scopeWhereSearch(Builder $query, string $search): void
{
$query->where('name', 'LIKE', '%'.$search.'%');
}
/**
* @return Collection|LengthAwarePaginator
*/
public function scopePaginateData(Builder $query, string $limit)
{
if ($limit == 'all') {
return $query->get();
}
return $query->paginate($limit);
}
}
@@ -1,111 +0,0 @@
<?php
namespace App\Domains\Taxation\Policies;
use App\Domains\Accounts\Models\User;
use App\Domains\Taxation\Models\TaxType;
use Illuminate\Auth\Access\HandlesAuthorization;
use Silber\Bouncer\BouncerFacade;
class TaxTypePolicy
{
use HandlesAuthorization;
/**
* Determine whether the user can view any models.
*
* @return mixed
*/
public function viewAny(User $user): bool
{
if (BouncerFacade::can('view-tax-type', TaxType::class)) {
return true;
}
return false;
}
/**
* Determine whether the user can view the model.
*
* @return mixed
*/
public function view(User $user, TaxType $taxType): bool
{
if (BouncerFacade::can('view-tax-type', $taxType) && $user->hasCompany($taxType->company_id)) {
return true;
}
return false;
}
/**
* Determine whether the user can create models.
*
* @return mixed
*/
public function create(User $user): bool
{
if (BouncerFacade::can('create-tax-type', TaxType::class)) {
return true;
}
return false;
}
/**
* Determine whether the user can update the model.
*
* @return mixed
*/
public function update(User $user, TaxType $taxType): bool
{
if (BouncerFacade::can('edit-tax-type', $taxType) && $user->hasCompany($taxType->company_id)) {
return true;
}
return false;
}
/**
* Determine whether the user can delete the model.
*
* @return mixed
*/
public function delete(User $user, TaxType $taxType): bool
{
if (BouncerFacade::can('delete-tax-type', $taxType) && $user->hasCompany($taxType->company_id)) {
return true;
}
return false;
}
/**
* Determine whether the user can restore the model.
*
* @return mixed
*/
public function restore(User $user, TaxType $taxType): bool
{
if (BouncerFacade::can('delete-tax-type', $taxType) && $user->hasCompany($taxType->company_id)) {
return true;
}
return false;
}
/**
* Determine whether the user can permanently delete the model.
*
* @return mixed
*/
public function forceDelete(User $user, TaxType $taxType): bool
{
if (BouncerFacade::can('delete-tax-type', $taxType) && $user->hasCompany($taxType->company_id)) {
return true;
}
return false;
}
}