diff --git a/app/Http/Controllers/Admin/Settings/DiskController.php b/app/Http/Controllers/Admin/Settings/DiskController.php index a45925be..95033655 100644 --- a/app/Http/Controllers/Admin/Settings/DiskController.php +++ b/app/Http/Controllers/Admin/Settings/DiskController.php @@ -6,12 +6,17 @@ use App\Http\Controllers\Controller; use App\Http\Requests\DiskEnvironmentRequest; use App\Http\Resources\FileDiskResource; use App\Models\FileDisk; +use App\Services\FileDiskService; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; use Illuminate\Http\Response; class DiskController extends Controller { + public function __construct( + private readonly FileDiskService $fileDiskService, + ) {} + /** * @return JsonResponse */ @@ -34,11 +39,11 @@ class DiskController extends Controller { $this->authorize('manage file disk'); - if (! FileDisk::validateCredentials($request->credentials, $request->driver)) { + if (! $this->fileDiskService->validateCredentials($request->credentials, $request->driver)) { return respondJson('invalid_credentials', 'Invalid Credentials.'); } - $disk = FileDisk::createDisk($request); + $disk = $this->fileDiskService->create($request); return new FileDiskResource($disk); } @@ -55,13 +60,13 @@ class DiskController extends Controller $driver = $request->driver; if ($credentials && $driver && $disk->type !== 'SYSTEM') { - if (! FileDisk::validateCredentials($credentials, $driver)) { + if (! $this->fileDiskService->validateCredentials($credentials, $driver)) { return respondJson('invalid_credentials', 'Invalid Credentials.'); } - $disk->updateDisk($request); + $this->fileDiskService->update($disk, $request); } elseif ($request->set_as_default) { - $disk->setAsDefaultDisk(); + $this->fileDiskService->setAsDefault($disk); } return new FileDiskResource($disk); diff --git a/app/Http/Controllers/Company/CustomField/CustomFieldsController.php b/app/Http/Controllers/Company/CustomField/CustomFieldsController.php index 1643e1fb..8ec991a8 100644 --- a/app/Http/Controllers/Company/CustomField/CustomFieldsController.php +++ b/app/Http/Controllers/Company/CustomField/CustomFieldsController.php @@ -6,11 +6,16 @@ use App\Http\Controllers\Controller; use App\Http\Requests\CustomFieldRequest; use App\Http\Resources\CustomFieldResource; use App\Models\CustomField; +use App\Services\CustomFieldService; use Illuminate\Http\Request; use Illuminate\Http\Response; class CustomFieldsController extends Controller { + public function __construct( + private readonly CustomFieldService $customFieldService, + ) {} + /** * Display a listing of the resource. * @@ -40,7 +45,7 @@ class CustomFieldsController extends Controller { $this->authorize('create', CustomField::class); - $customField = CustomField::createCustomField($request); + $customField = $this->customFieldService->create($request); return new CustomFieldResource($customField); } @@ -69,7 +74,7 @@ class CustomFieldsController extends Controller { $this->authorize('update', $customField); - $customField->updateCustomField($request); + $this->customFieldService->update($customField, $request); return new CustomFieldResource($customField); } diff --git a/app/Http/Controllers/Company/ExchangeRate/ExchangeRateProviderController.php b/app/Http/Controllers/Company/ExchangeRate/ExchangeRateProviderController.php index a2074c68..a2ca92f2 100644 --- a/app/Http/Controllers/Company/ExchangeRate/ExchangeRateProviderController.php +++ b/app/Http/Controllers/Company/ExchangeRate/ExchangeRateProviderController.php @@ -14,6 +14,7 @@ use App\Models\ExchangeRateProvider; use App\Models\Invoice; use App\Models\Payment; use App\Models\Tax; +use App\Services\ExchangeRateProviderService; use App\Traits\ExchangeRateProvidersTrait; use Illuminate\Http\Request; use Illuminate\Http\Response; @@ -23,6 +24,10 @@ class ExchangeRateProviderController extends Controller { use ExchangeRateProvidersTrait; + public function __construct( + private readonly ExchangeRateProviderService $exchangeRateProviderService, + ) {} + /** * Display a listing of the resource. * @@ -49,16 +54,16 @@ class ExchangeRateProviderController extends Controller { $this->authorize('create', ExchangeRateProvider::class); - $query = ExchangeRateProvider::checkActiveCurrencies($request); + $query = $this->exchangeRateProviderService->checkActiveCurrencies($request); if (count($query) !== 0) { return respondJson('currency_used', 'Currency used.'); } - $checkConverterApi = ExchangeRateProvider::checkExchangeRateProviderStatus($request); + $checkConverterApi = $this->exchangeRateProviderService->checkProviderStatus($request); if ($checkConverterApi->status() == 200) { - $exchangeRateProvider = ExchangeRateProvider::createFromRequest($request); + $exchangeRateProvider = $this->exchangeRateProviderService->create($request); return new ExchangeRateProviderResource($exchangeRateProvider); } @@ -88,16 +93,16 @@ class ExchangeRateProviderController extends Controller { $this->authorize('update', $exchangeRateProvider); - $query = $exchangeRateProvider->checkUpdateActiveCurrencies($request); + $query = $this->exchangeRateProviderService->checkUpdateActiveCurrencies($exchangeRateProvider, $request); if (count($query) !== 0) { return respondJson('currency_used', 'Currency used.'); } - $checkConverterApi = ExchangeRateProvider::checkExchangeRateProviderStatus($request); + $checkConverterApi = $this->exchangeRateProviderService->checkProviderStatus($request); if ($checkConverterApi->status() == 200) { - $exchangeRateProvider->updateFromRequest($request); + $this->exchangeRateProviderService->update($exchangeRateProvider, $request); return new ExchangeRateProviderResource($exchangeRateProvider); } diff --git a/app/Http/Controllers/Company/Item/ItemsController.php b/app/Http/Controllers/Company/Item/ItemsController.php index d348e72a..c50921aa 100644 --- a/app/Http/Controllers/Company/Item/ItemsController.php +++ b/app/Http/Controllers/Company/Item/ItemsController.php @@ -8,11 +8,16 @@ use App\Http\Requests\DeleteItemsRequest; use App\Http\Resources\ItemResource; use App\Models\Item; use App\Models\TaxType; +use App\Services\ItemService; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; class ItemsController extends Controller { + public function __construct( + private readonly ItemService $itemService, + ) {} + /** * Retrieve a list of existing Items. * @@ -48,7 +53,7 @@ class ItemsController extends Controller { $this->authorize('create', Item::class); - $item = Item::createItem($request); + $item = $this->itemService->create($request); return new ItemResource($item); } @@ -75,7 +80,7 @@ class ItemsController extends Controller { $this->authorize('update', $item); - $item = $item->updateItem($request); + $item = $this->itemService->update($item, $request); return new ItemResource($item); } diff --git a/app/Services/CustomFieldService.php b/app/Services/CustomFieldService.php new file mode 100644 index 00000000..5a6cab83 --- /dev/null +++ b/app/Services/CustomFieldService.php @@ -0,0 +1,28 @@ +validated(); + $data[getCustomFieldValueKey($request->type)] = $request->default_answer; + $data['company_id'] = $request->header('company'); + $data['slug'] = clean_slug($request->model_type, $request->name); + + return CustomField::create($data); + } + + public function update(CustomField $customField, Request $request): CustomField + { + $data = $request->validated(); + $data[getCustomFieldValueKey($request->type)] = $request->default_answer; + $customField->update($data); + + return $customField; + } +} diff --git a/app/Services/ExchangeRateProviderService.php b/app/Services/ExchangeRateProviderService.php new file mode 100644 index 00000000..0234ebde --- /dev/null +++ b/app/Services/ExchangeRateProviderService.php @@ -0,0 +1,116 @@ +getExchangeRateProviderPayload()); + } + + public function update(ExchangeRateProvider $provider, ExchangeRateProviderRequest $request): ExchangeRateProvider + { + $provider->update($request->getExchangeRateProviderPayload()); + + return $provider; + } + + public function checkActiveCurrencies($request) + { + return ExchangeRateProvider::whereJsonContains('currencies', $request->currencies) + ->where('active', true) + ->get(); + } + + public function checkUpdateActiveCurrencies(ExchangeRateProvider $provider, $request) + { + return ExchangeRateProvider::where('active', $request->active) + ->where('id', '<>', $provider->id) + ->whereJsonContains('currencies', $request->currencies) + ->get(); + } + + public function checkProviderStatus($request) + { + switch ($request['driver']) { + case 'currency_freak': + $url = 'https://api.currencyfreaks.com/latest?apikey='.$request['key'].'&symbols=INR&base=USD'; + $response = Http::get($url)->json(); + + if (array_key_exists('success', $response)) { + if ($response['success'] == false) { + return respondJson($response['error']['message'], $response['error']['message']); + } + } + + return response()->json([ + 'exchangeRate' => array_values($response['rates']), + ], 200); + + case 'currency_layer': + $url = 'http://api.currencylayer.com/live?access_key='.$request['key'].'&source=INR¤cies=USD'; + $response = Http::get($url)->json(); + + if (array_key_exists('success', $response)) { + if ($response['success'] == false) { + return respondJson($response['error']['info'], $response['error']['info']); + } + } + + return response()->json([ + 'exchangeRate' => array_values($response['quotes']), + ], 200); + + case 'open_exchange_rate': + $url = 'https://openexchangerates.org/api/latest.json?app_id='.$request['key'].'&base=INR&symbols=USD'; + $response = Http::get($url)->json(); + + if (array_key_exists('error', $response)) { + return respondJson($response['message'], $response['description']); + } + + return response()->json([ + 'exchangeRate' => array_values($response['rates']), + ], 200); + + case 'currency_converter': + $url = $this->getCurrencyConverterUrl($request['driver_config']); + $url = $url.'/api/v7/convert?apiKey='.$request['key']; + + $query = 'INR_USD'; + $url = $url."&q={$query}".'&compact=y'; + $response = Http::get($url)->json(); + + return response()->json([ + 'exchangeRate' => array_values($response[$query]), + ], 200); + } + } + + public function addExchangeRateLog($model): ExchangeRateLog + { + return ExchangeRateLog::create([ + 'exchange_rate' => $model->exchange_rate, + 'company_id' => $model->company_id, + 'base_currency_id' => $model->currency_id, + 'currency_id' => CompanySetting::getSetting('currency', $model->company_id), + ]); + } + + private function getCurrencyConverterUrl($data): string + { + return match ($data['type']) { + 'PREMIUM' => 'https://api.currconv.com', + 'PREPAID' => 'https://prepaid.currconv.com', + 'FREE' => 'https://free.currconv.com', + 'DEDICATED' => $data['url'], + }; + } +} diff --git a/app/Services/FileDiskService.php b/app/Services/FileDiskService.php new file mode 100644 index 00000000..35265367 --- /dev/null +++ b/app/Services/FileDiskService.php @@ -0,0 +1,85 @@ +set_as_default) { + $this->clearDefaults(); + } + + return FileDisk::create([ + 'credentials' => $request->credentials, + 'name' => $request->name, + 'driver' => $request->driver, + 'set_as_default' => $request->set_as_default, + 'company_id' => $request->header('company'), + ]); + } + + public function update(FileDisk $disk, Request $request): FileDisk + { + $data = [ + 'credentials' => $request->credentials, + 'name' => $request->name, + 'driver' => $request->driver, + ]; + + if (! $disk->set_as_default) { + if ($request->set_as_default) { + $this->clearDefaults(); + } + + $data['set_as_default'] = $request->set_as_default; + } + + $disk->update($data); + + return $disk; + } + + public function setAsDefault(FileDisk $disk): FileDisk + { + $this->clearDefaults(); + + $disk->set_as_default = true; + $disk->save(); + + return $disk; + } + + public function validateCredentials(array $credentials, string $driver): bool + { + FileDisk::setFilesystem(collect($credentials), $driver); + + $prefix = env('DYNAMIC_DISK_PREFIX', 'temp_'); + + try { + $root = ''; + if ($driver == 'dropbox') { + $root = $credentials['root'].'/'; + } + \Storage::disk($prefix.$driver)->put($root.'invoiceshelf_temp.text', 'Check Credentials'); + + if (\Storage::disk($prefix.$driver)->exists($root.'invoiceshelf_temp.text')) { + \Storage::disk($prefix.$driver)->delete($root.'invoiceshelf_temp.text'); + + return true; + } + } catch (\Exception $e) { + return false; + } + + return false; + } + + private function clearDefaults(): void + { + FileDisk::query()->update(['set_as_default' => false]); + } +} diff --git a/app/Services/ItemService.php b/app/Services/ItemService.php new file mode 100644 index 00000000..de338f3a --- /dev/null +++ b/app/Services/ItemService.php @@ -0,0 +1,49 @@ +validated(); + $data['company_id'] = $request->header('company'); + $data['creator_id'] = Auth::id(); + $data['currency_id'] = CompanySetting::getSetting('currency', $request->header('company')); + $item = Item::create($data); + + if ($request->has('taxes')) { + foreach ($request->taxes as $tax) { + $item->tax_per_item = true; + $item->save(); + $tax['company_id'] = $request->header('company'); + $item->taxes()->create($tax); + } + } + + return Item::with('taxes')->find($item->id); + } + + public function update(Item $item, Request $request): Item + { + $item->update($request->validated()); + + $item->taxes()->delete(); + + if ($request->has('taxes')) { + foreach ($request->taxes as $tax) { + $item->tax_per_item = true; + $item->save(); + $tax['company_id'] = $request->header('company'); + $item->taxes()->create($tax); + } + } + + return Item::with('taxes')->find($item->id); + } +} diff --git a/app/Services/TransactionService.php b/app/Services/TransactionService.php new file mode 100644 index 00000000..5922eda9 --- /dev/null +++ b/app/Services/TransactionService.php @@ -0,0 +1,30 @@ +unique_hash = Hashids::connection(Transaction::class)->encode($transaction->id); + $transaction->save(); + + return $transaction; + } + + public function complete(Transaction $transaction): void + { + $transaction->status = Transaction::SUCCESS; + $transaction->save(); + } + + public function fail(Transaction $transaction): void + { + $transaction->status = Transaction::FAILED; + $transaction->save(); + } +}