diff --git a/app/Export/CSV/QuoteExport.php b/app/Export/CSV/QuoteExport.php index 6decca083870..4844963f4ea2 100644 --- a/app/Export/CSV/QuoteExport.php +++ b/app/Export/CSV/QuoteExport.php @@ -31,11 +31,11 @@ class QuoteExport extends BaseExport private Decorator $decorator; - private array $decorate_keys = [ - 'client', - 'currency', - 'invoice', - ]; + // private array $decorate_keys = [ + // 'client', + // 'currency', + // 'invoice', + // ]; public function __construct(Company $company, array $input) { diff --git a/app/Export/CSV/TaskExport.php b/app/Export/CSV/TaskExport.php index 47423c23e2b3..b04020317801 100644 --- a/app/Export/CSV/TaskExport.php +++ b/app/Export/CSV/TaskExport.php @@ -31,7 +31,7 @@ class TaskExport extends BaseExport public string $date_key = 'created_at'; - private string $date_format = 'YYYY-MM-DD'; + private string $date_format = 'Y-m-d'; public Writer $csv; @@ -180,13 +180,7 @@ class TaskExport extends BaseExport $logs = json_decode($task->time_log, 1); - $date_format_default = 'Y-m-d'; - - $date_format = DateFormat::find($task->company->settings->date_format_id); - - if ($date_format) { - $date_format_default = $date_format->format; - } + $date_format_default = $this->date_format; foreach ($logs as $key => $item) { if (in_array('task.start_date', $this->input['report_keys']) || in_array('start_date', $this->input['report_keys'])) { @@ -236,7 +230,7 @@ class TaskExport extends BaseExport */ protected function addTaskStatusFilter(Builder $query, string $status): Builder { - + /** @var array $status_parameters */ $status_parameters = explode(',', $status); if (in_array('all', $status_parameters) || count($status_parameters) == 0) { diff --git a/app/Export/CSV/VendorExport.php b/app/Export/CSV/VendorExport.php index c04f83e8c4c4..5b67792d2b7a 100644 --- a/app/Export/CSV/VendorExport.php +++ b/app/Export/CSV/VendorExport.php @@ -171,16 +171,16 @@ class VendorExport extends BaseExport return $entity; } - private function calculateStatus($vendor) - { - if ($vendor->is_deleted) { - return ctrans('texts.deleted'); - } + // private function calculateStatus($vendor) + // { + // if ($vendor->is_deleted) { + // return ctrans('texts.deleted'); + // } - if ($vendor->deleted_at) { - return ctrans('texts.archived'); - } + // if ($vendor->deleted_at) { + // return ctrans('texts.archived'); + // } - return ctrans('texts.active'); - } + // return ctrans('texts.active'); + // } } diff --git a/app/Factory/RecurringExpenseToExpenseFactory.php b/app/Factory/RecurringExpenseToExpenseFactory.php index 8ba5f96322d0..d1903408409b 100644 --- a/app/Factory/RecurringExpenseToExpenseFactory.php +++ b/app/Factory/RecurringExpenseToExpenseFactory.php @@ -82,11 +82,15 @@ class RecurringExpenseToExpenseFactory } else { $locale = $recurring_expense->company->locale(); - $date_formats = Cache::get('date_formats'); + //@deprecated + // $date_formats = Cache::get('date_formats'); - $date_format = $date_formats->filter(function ($item) use ($recurring_expense) { + /** @var \Illuminate\Support\Collection<\App\Models\DateFormat> */ + $date_formats = app('date_formats'); + + $date_format = $date_formats->first(function ($item) use ($recurring_expense) { return $item->id == $recurring_expense->company->settings->date_format_id; - })->first()->format; + })->format; } Carbon::setLocale($locale); @@ -144,7 +148,7 @@ class RecurringExpenseToExpenseFactory continue; } - if (Str::contains($match, '|')) { + // if (Str::contains($match, '|')) { $parts = explode('|', $match); // [ '[MONTH', 'MONTH+2]' ] $left = substr($parts[0], 1); // 'MONTH' @@ -182,7 +186,7 @@ class RecurringExpenseToExpenseFactory $value, 1 ); - } + // } } // Second case with more common calculations. diff --git a/app/Filters/ExpenseFilters.php b/app/Filters/ExpenseFilters.php index 108dc359d811..ca2b1b09bdde 100644 --- a/app/Filters/ExpenseFilters.php +++ b/app/Filters/ExpenseFilters.php @@ -79,7 +79,7 @@ class ExpenseFilters extends QueryFilters $this->builder->where(function ($query) use ($status_parameters) { if (in_array('logged', $status_parameters)) { $query->orWhere(function ($query) { - $query->where('amount', '>', 0) + $query->where('amount', '>=', 0) ->whereNull('invoice_id') ->whereNull('payment_date') ->where('should_be_invoiced', false); diff --git a/app/Filters/InvoiceFilters.php b/app/Filters/InvoiceFilters.php index 3ef024429485..0343402a37b2 100644 --- a/app/Filters/InvoiceFilters.php +++ b/app/Filters/InvoiceFilters.php @@ -271,6 +271,7 @@ class InvoiceFilters extends QueryFilters if (count($parts) != 2) { return $this->builder; } + try { $start_date = Carbon::parse($parts[0]); @@ -281,7 +282,6 @@ class InvoiceFilters extends QueryFilters return $this->builder; } - return $this->builder; } /** @@ -307,7 +307,6 @@ class InvoiceFilters extends QueryFilters return $this->builder; } - return $this->builder; } diff --git a/app/Filters/PaymentFilters.php b/app/Filters/PaymentFilters.php index 9f3a6b781d51..7927daf08989 100644 --- a/app/Filters/PaymentFilters.php +++ b/app/Filters/PaymentFilters.php @@ -204,7 +204,6 @@ class PaymentFilters extends QueryFilters return $this->builder; } - return $this->builder; } /** diff --git a/app/Filters/RecurringInvoiceFilters.php b/app/Filters/RecurringInvoiceFilters.php index 56ac04619c99..8886d6aec025 100644 --- a/app/Filters/RecurringInvoiceFilters.php +++ b/app/Filters/RecurringInvoiceFilters.php @@ -162,9 +162,10 @@ class RecurringInvoiceFilters extends QueryFilters return $this->builder; } + /** @var array $key_parameters */ $key_parameters = explode(',', $value); - if (count($key_parameters)) { + if (count($key_parameters) > 0) { return $this->builder->where(function ($query) use ($key_parameters) { foreach ($key_parameters as $key) { $query->orWhereJsonContains('line_items', ['product_key' => $key]); @@ -183,6 +184,7 @@ class RecurringInvoiceFilters extends QueryFilters */ public function next_send_between(string $range = ''): Builder { + /** @var array $parts */ $parts = explode('|', $range); if (!isset($parts[0]) || !isset($parts[1])) { diff --git a/app/Filters/TaskFilters.php b/app/Filters/TaskFilters.php index a98c6ae5b500..3b26e004742b 100644 --- a/app/Filters/TaskFilters.php +++ b/app/Filters/TaskFilters.php @@ -175,6 +175,7 @@ class TaskFilters extends QueryFilters return $this->builder; } + /** @var array $status_parameters */ $status_parameters = explode(',', $value); if(count($status_parameters) >= 1) { diff --git a/app/Helpers/Bank/Nordigen/Transformer/TransactionTransformer.php b/app/Helpers/Bank/Nordigen/Transformer/TransactionTransformer.php index d2259150e181..8e85a806289d 100644 --- a/app/Helpers/Bank/Nordigen/Transformer/TransactionTransformer.php +++ b/app/Helpers/Bank/Nordigen/Transformer/TransactionTransformer.php @@ -156,22 +156,16 @@ class TransactionTransformer implements BankRevenueInterface private function convertCurrency(string $code) { - $currencies = Cache::get('currencies'); + $currencies = app('currencies'); - if (!$currencies) { - $this->buildCache(true); - } - - $currency = $currencies->filter(function ($item) use ($code) { + $currency = $currencies->first(function ($item) use ($code) { + /** @var \App\Models\Currency $item */ return $item->code == $code; - })->first(); - - if ($currency) { - return $currency->id; - } - - return 1; + }); + /** @var \App\Models\Currency $currency */ + return $currency ? $currency->id : 1; //@phpstan-ignore-line + } private function formatDate(string $input) diff --git a/app/Helpers/Bank/Yodlee/Transformer/IncomeTransformer.php b/app/Helpers/Bank/Yodlee/Transformer/IncomeTransformer.php index d804df272b06..d14e67bc012c 100644 --- a/app/Helpers/Bank/Yodlee/Transformer/IncomeTransformer.php +++ b/app/Helpers/Bank/Yodlee/Transformer/IncomeTransformer.php @@ -171,20 +171,16 @@ class IncomeTransformer implements BankRevenueInterface private function convertCurrency(string $code) { - $currencies = Cache::get('currencies'); - if (! $currencies) { - $this->buildCache(true); - } + $currencies = app('currencies'); - $currency = $currencies->filter(function ($item) use ($code) { + $currency = $currencies->first(function ($item) use ($code) { + /** @var \App\Models\Currency $item */ return $item->code == $code; - })->first(); + }); - if ($currency) { - return $currency->id; - } + /** @var \App\Models\Currency $currency */ + return $currency ? $currency->id : 1; //@phpstan-ignore-line - return 1; } } diff --git a/app/Helpers/Epc/EpcQrGenerator.php b/app/Helpers/Epc/EpcQrGenerator.php index 87bb585ba6e4..ccdee6e65efe 100644 --- a/app/Helpers/Epc/EpcQrGenerator.php +++ b/app/Helpers/Epc/EpcQrGenerator.php @@ -26,15 +26,15 @@ use BaconQrCode\Writer; */ class EpcQrGenerator { - private array $sepa = [ - 'serviceTag' => 'BCD', - 'version' => 2, - 'characterSet' => 1, - 'identification' => 'SCT', - 'bic' => '', - 'purpose' => '', + // private array $sepa = [ + // 'serviceTag' => 'BCD', + // 'version' => 2, + // 'characterSet' => 1, + // 'identification' => 'SCT', + // 'bic' => '', + // 'purpose' => '', - ]; + // ]; public function __construct(protected Company $company, protected Invoice|RecurringInvoice $invoice, protected float $amount) { @@ -61,13 +61,7 @@ class EpcQrGenerator } catch(\Throwable $e) { nlog("EPC QR failure => ".$e->getMessage()); return ''; - } catch(\Exception $e) { - nlog("EPC QR failure => ".$e->getMessage()); - return ''; - } catch(InvalidArgumentException $e) { - nlog("EPC QR failure => ".$e->getMessage()); - return ''; - } + } } diff --git a/app/Helpers/Invoice/InvoiceItemSum.php b/app/Helpers/Invoice/InvoiceItemSum.php index dc946874f043..ef2cddb0ef3b 100644 --- a/app/Helpers/Invoice/InvoiceItemSum.php +++ b/app/Helpers/Invoice/InvoiceItemSum.php @@ -29,6 +29,7 @@ class InvoiceItemSum use Discounter; use Taxer; + //@phpstan-ignore-next-line private array $eu_tax_jurisdictions = [ 'AT', // Austria 'BE', // Belgium @@ -170,7 +171,7 @@ class InvoiceItemSum private function shouldCalculateTax(): self { - if (!$this->invoice->company?->calculate_taxes || $this->invoice->company->account->isFreeHostedClient()) { + if (!$this->invoice->company?->calculate_taxes || $this->invoice->company->account->isFreeHostedClient()) { //@phpstan-ignore-line $this->calc_tax = false; return $this; } diff --git a/app/Helpers/Invoice/InvoiceItemSumInclusive.php b/app/Helpers/Invoice/InvoiceItemSumInclusive.php index 3ecbf7431d36..eacb13afb9e5 100644 --- a/app/Helpers/Invoice/InvoiceItemSumInclusive.php +++ b/app/Helpers/Invoice/InvoiceItemSumInclusive.php @@ -27,7 +27,7 @@ class InvoiceItemSumInclusive use Discounter; use Taxer; - + //@phpstan-ignore-next-line private array $eu_tax_jurisdictions = [ 'AT', // Austria 'BE', // Belgium @@ -98,6 +98,7 @@ class InvoiceItemSumInclusive private $total_taxes; + /** @phpstan-ignore-next-line */ private $item; private $line_items; @@ -399,7 +400,7 @@ class InvoiceItemSumInclusive private function shouldCalculateTax(): self { - if (!$this->invoice->company?->calculate_taxes || $this->invoice->company->account->isFreeHostedClient()) { + if (!$this->invoice->company?->calculate_taxes || $this->invoice->company->account->isFreeHostedClient()) {//@phpstan-ignore-line $this->calc_tax = false; return $this; } diff --git a/app/Helpers/Invoice/ProRata.php b/app/Helpers/Invoice/ProRata.php index e012036ad5d4..d5f42c0c9573 100644 --- a/app/Helpers/Invoice/ProRata.php +++ b/app/Helpers/Invoice/ProRata.php @@ -58,12 +58,12 @@ class ProRata * Prepares the line items of an invoice * to be pro rata refunded. * - * @param Invoice $invoice + * @param ?Invoice $invoice * @param bool $is_credit * @return array * @throws Exception */ - public function refundItems(Invoice $invoice, $is_credit = false): array + public function refundItems(?Invoice $invoice, $is_credit = false): array { if (! $invoice) { return []; diff --git a/app/Http/Controllers/Auth/ContactForgotPasswordController.php b/app/Http/Controllers/Auth/ContactForgotPasswordController.php index e592da6c3065..ac275626dc43 100644 --- a/app/Http/Controllers/Auth/ContactForgotPasswordController.php +++ b/app/Http/Controllers/Auth/ContactForgotPasswordController.php @@ -118,7 +118,7 @@ class ContactForgotPasswordController extends Controller })->first(); } - $response = false; + // $response = false; if ($contact) { /* Update all instances of the client */ @@ -131,16 +131,16 @@ class ContactForgotPasswordController extends Controller } if ($request->ajax()) { - if ($response == Password::RESET_THROTTLED) { + if ($response == Password::RESET_THROTTLED) { // @phpstan-ignore-line return response()->json(['message' => ctrans('passwords.throttled'), 'status' => false], 429); } - return $response == Password::RESET_LINK_SENT + return $response == Password::RESET_LINK_SENT // @phpstan-ignore-line ? response()->json(['message' => 'Reset link sent to your email.', 'status' => true], 201) : response()->json(['message' => 'Email not found', 'status' => false], 401); } - return $response == Password::RESET_LINK_SENT + return $response == Password::RESET_LINK_SENT // @phpstan-ignore-line ? $this->sendResetLinkResponse($request, $response) : $this->sendResetLinkFailedResponse($request, $response); } diff --git a/app/Http/Controllers/Auth/ContactLoginController.php b/app/Http/Controllers/Auth/ContactLoginController.php index 8b560e7f6892..5a72419244cb 100644 --- a/app/Http/Controllers/Auth/ContactLoginController.php +++ b/app/Http/Controllers/Auth/ContactLoginController.php @@ -55,7 +55,7 @@ class ContactLoginController extends Controller $company = Company::where('company_key', $company_key)->first(); } - /** @var \App\Models\Company $company **/ + /** @var ?\App\Models\Company $company **/ if ($company) { $account = $company->account; } elseif (! $company && strpos($request->getHost(), config('ninja.app_domain')) !== false) { diff --git a/app/Http/Controllers/Auth/ResetPasswordController.php b/app/Http/Controllers/Auth/ResetPasswordController.php index 08c02b6892f6..2e066abeb78c 100644 --- a/app/Http/Controllers/Auth/ResetPasswordController.php +++ b/app/Http/Controllers/Auth/ResetPasswordController.php @@ -137,8 +137,8 @@ class ResetPasswordController extends Controller return redirect('/#/login'); } - return redirect($this->redirectPath()) - ->with('status', trans($response)); + // return redirect($this->redirectPath()) + // ->with('status', trans($response)); } } diff --git a/app/Http/Controllers/BaseController.php b/app/Http/Controllers/BaseController.php index 76b81fb84d09..e9b7fcc96dfa 100644 --- a/app/Http/Controllers/BaseController.php +++ b/app/Http/Controllers/BaseController.php @@ -1035,7 +1035,7 @@ class BaseController extends Controller $resource = new Item($item, $transformer, $this->entity_type); - /** @var \App\Models\User $user */ + /** @var ?\App\Models\User $user */ $user = auth()->user(); if ($user && request()->include_static) { diff --git a/app/Http/Controllers/BrevoController.php b/app/Http/Controllers/BrevoController.php index c096a42fe4b9..e0e94e8fa71b 100644 --- a/app/Http/Controllers/BrevoController.php +++ b/app/Http/Controllers/BrevoController.php @@ -19,7 +19,6 @@ use Illuminate\Http\Request; */ class BrevoController extends BaseController { - private $invitation; public function __construct() { diff --git a/app/Http/Controllers/ClientController.php b/app/Http/Controllers/ClientController.php index 38f1f3a0397e..76fe6c661abd 100644 --- a/app/Http/Controllers/ClientController.php +++ b/app/Http/Controllers/ClientController.php @@ -141,7 +141,7 @@ class ClientController extends BaseController return $request->disallowUpdate(); } - /** @var \App\Models\User $user */ + /** @var ?\App\Models\User $user */ $user = auth()->user(); $client = $this->client_repo->save($request->all(), $client); @@ -426,7 +426,7 @@ class ClientController extends BaseController try { - /** @var \Postmark\Models\DynamicResponseModel $response */ + /** @var ?\Postmark\Models\DynamicResponseModel $response */ $response = $postmark->activateBounce((int)$bounce_id); if($response && $response?->Message == 'OK' && !$response->Bounce->Inactive && $response->Bounce->Email) { diff --git a/app/Http/Controllers/ClientPortal/InvitationController.php b/app/Http/Controllers/ClientPortal/InvitationController.php index 5120f0c0a433..f1993693a90f 100644 --- a/app/Http/Controllers/ClientPortal/InvitationController.php +++ b/app/Http/Controllers/ClientPortal/InvitationController.php @@ -146,6 +146,7 @@ class InvitationController extends Controller } + private function fireEntityViewedEvent($invitation, $entity_string) { switch ($entity_string) { diff --git a/app/Http/Controllers/ClientPortal/InvoiceController.php b/app/Http/Controllers/ClientPortal/InvoiceController.php index b446a8d805b2..0d8449daae99 100644 --- a/app/Http/Controllers/ClientPortal/InvoiceController.php +++ b/app/Http/Controllers/ClientPortal/InvoiceController.php @@ -97,12 +97,12 @@ class InvoiceController extends Controller $invitation = false; - match($data['entity_type'] ?? false) { + match($data['entity_type'] ?? 'invoice') { 'invoice' => $invitation = InvoiceInvitation::withTrashed()->find($data['invitation_id']), 'quote' => $invitation = QuoteInvitation::withTrashed()->find($data['invitation_id']), 'credit' => $invitation = CreditInvitation::withTrashed()->find($data['invitation_id']), 'recurring_invoice' => $invitation = RecurringInvoiceInvitation::withTrashed()->find($data['invitation_id']), - false => $invitation = false, + default => $invitation = false, }; if (! $invitation) { diff --git a/app/Http/Controllers/ClientPortal/PaymentController.php b/app/Http/Controllers/ClientPortal/PaymentController.php index bce4399d3be8..b2b63c0cea9e 100644 --- a/app/Http/Controllers/ClientPortal/PaymentController.php +++ b/app/Http/Controllers/ClientPortal/PaymentController.php @@ -77,6 +77,7 @@ class PaymentController extends Controller 'EUR' => $data = $bt->formatDataforEur($payment_intent), 'JPY' => $data = $bt->formatDataforJp($payment_intent), 'GBP' => $data = $bt->formatDataforUk($payment_intent), + default => $data = $bt->formatDataforUk($payment_intent), }; $gateway = $stripe; diff --git a/app/Http/Controllers/ClientPortal/SubscriptionPurchaseController.php b/app/Http/Controllers/ClientPortal/SubscriptionPurchaseController.php index 579047f06d60..677fb3cceeff 100644 --- a/app/Http/Controllers/ClientPortal/SubscriptionPurchaseController.php +++ b/app/Http/Controllers/ClientPortal/SubscriptionPurchaseController.php @@ -90,15 +90,20 @@ class SubscriptionPurchaseController extends Controller * Set locale for incoming request. * * @param string $locale + * @return string */ - private function setLocale(string $locale): void + private function setLocale(string $locale): string { - $record = Cache::get('languages')->filter(function ($item) use ($locale) { - return $item->locale == $locale; - })->first(); + + /** @var \Illuminate\Support\Collection<\App\Models\Language> */ + $languages = app('languages'); - if ($record) { - App::setLocale($record->locale); - } + $record = $languages->first(function ($item) use ($locale) { + /** @var \App\Models\Language $item */ + return $item->locale == $locale; + }); + + return $record ? $record->locale : 'en'; + } } diff --git a/app/Http/Controllers/CompanyController.php b/app/Http/Controllers/CompanyController.php index 520bd201905b..efa8c8081096 100644 --- a/app/Http/Controllers/CompanyController.php +++ b/app/Http/Controllers/CompanyController.php @@ -693,7 +693,7 @@ class CompanyController extends BaseController public function updateOriginTaxData(DefaultCompanyRequest $request, Company $company) { - if($company->settings->country_id == "840" && !$company?->account->isFreeHostedClient()) { + if($company->settings->country_id == "840" && !$company->account->isFreeHostedClient()) { try { (new CompanyTaxRate($company))->handle(); } catch(\Exception $e) { diff --git a/app/Http/Controllers/CompanyUserController.php b/app/Http/Controllers/CompanyUserController.php index c9526fec3604..89dee72a52bd 100644 --- a/app/Http/Controllers/CompanyUserController.php +++ b/app/Http/Controllers/CompanyUserController.php @@ -119,8 +119,6 @@ class CompanyUserController extends BaseController if (! $company_user) { throw new ModelNotFoundException(ctrans('texts.company_user_not_found')); - - return; } if ($auth_user->isAdmin()) { @@ -152,7 +150,6 @@ class CompanyUserController extends BaseController if (! $company_user) { throw new ModelNotFoundException(ctrans('texts.company_user_not_found')); - return; } $this->entity_type = User::class; diff --git a/app/Http/Controllers/CreditController.php b/app/Http/Controllers/CreditController.php index 63c419cff84f..d6fe802d4fe7 100644 --- a/app/Http/Controllers/CreditController.php +++ b/app/Http/Controllers/CreditController.php @@ -594,13 +594,11 @@ class CreditController extends BaseController $credit->service()->markPaid()->save(); return $this->itemResponse($credit); - break; case 'clone_to_credit': $credit = CloneCreditFactory::create($credit, auth()->user()->id); return $this->itemResponse($credit); - break; case 'history': // code... break; @@ -617,7 +615,7 @@ class CreditController extends BaseController return response()->streamDownload(function () use ($file) { echo $file; }, $credit->numberFormatter() . '.pdf', ['Content-Type' => 'application/pdf']); - break; + case 'archive': $this->credit_repository->archive($credit); @@ -655,7 +653,6 @@ class CreditController extends BaseController default: return response()->json(['message' => ctrans('texts.action_unavailable', ['action' => $action])], 400); - break; } } diff --git a/app/Http/Controllers/EmailController.php b/app/Http/Controllers/EmailController.php index 06cda32333e6..88d81f55f046 100644 --- a/app/Http/Controllers/EmailController.php +++ b/app/Http/Controllers/EmailController.php @@ -139,19 +139,19 @@ class EmailController extends BaseController return $this->itemResponse($entity_obj->fresh()); } - private function sendPurchaseOrder($entity_obj, $data, $template) - { - $this->entity_type = PurchaseOrder::class; + // private function sendPurchaseOrder($entity_obj, $data, $template) + // { + // $this->entity_type = PurchaseOrder::class; - $this->entity_transformer = PurchaseOrderTransformer::class; + // $this->entity_transformer = PurchaseOrderTransformer::class; - $data['template'] = $template; + // $data['template'] = $template; - PurchaseOrderEmail::dispatch($entity_obj, $entity_obj->company, $data); - $entity_obj->sendEvent(Webhook::EVENT_SENT_PURCHASE_ORDER, "vendor"); + // PurchaseOrderEmail::dispatch($entity_obj, $entity_obj->company, $data); + // $entity_obj->sendEvent(Webhook::EVENT_SENT_PURCHASE_ORDER, "vendor"); - return $this->itemResponse($entity_obj); - } + // return $this->itemResponse($entity_obj); + // } private function resolveClass(string $entity): string { diff --git a/app/Http/Controllers/MigrationController.php b/app/Http/Controllers/MigrationController.php index 85fec16ab097..11123bf830d7 100644 --- a/app/Http/Controllers/MigrationController.php +++ b/app/Http/Controllers/MigrationController.php @@ -280,186 +280,172 @@ class MigrationController extends BaseController } } - if (app()->environment() === 'local') { - } - - try { - return response()->json([ - '_id' => Str::uuid(), - 'method' => config('queue.default'), - 'started_at' => now(), - ], 200); - } finally { - // Controller logic here - - foreach ($companies as $company) { - if (! is_array($company)) { - continue; - } - - $company = (array) $company; - - $user = auth()->user(); - - $company_count = $user->account->companies()->count(); - $fresh_company = false; - - // Look for possible existing company (based on company keys). - $existing_company = Company::query()->whereRaw('BINARY `company_key` = ?', [$company['company_key']])->first(); - - App::forgetInstance('translator'); - $t = app('translator'); - $t->replace(Ninja::transformTranslations($user->account->companies()->first()->settings)); - App::setLocale($user->account->companies()->first()->getLocale()); - - if (! $existing_company && $company_count >= 10) { - $nmo = new NinjaMailerObject(); - $nmo->mailable = new MaxCompanies($user->account->companies()->first()); - $nmo->company = $user->account->companies()->first(); - $nmo->settings = $user->account->companies()->first()->settings; - $nmo->to_user = $user; - - if(!$this->silent_migration) { - NinjaMailerJob::dispatch($nmo, true); - } - - return; - } elseif ($existing_company && $company_count > 10) { - $nmo = new NinjaMailerObject(); - $nmo->mailable = new MaxCompanies($user->account->companies()->first()); - $nmo->company = $user->account->companies()->first(); - $nmo->settings = $user->account->companies()->first()->settings; - $nmo->to_user = $user; - - if(!$this->silent_migration) { - NinjaMailerJob::dispatch($nmo, true); - } - - return; - } - - $checks = [ - 'existing_company' => $existing_company ? (bool) 1 : false, - 'force' => array_key_exists('force', $company) ? (bool) $company['force'] : false, - ]; - - // If there's existing company and ** no ** force is provided - skip migration. - if ($checks['existing_company'] == true && $checks['force'] == false) { - nlog('Migrating: Existing company without force. (CASE_01)'); - - $nmo = new NinjaMailerObject(); - $nmo->mailable = new ExistingMigration($existing_company); - $nmo->company = $user->account->companies()->first(); - $nmo->settings = $user->account->companies()->first(); - $nmo->to_user = $user; - - if(!$this->silent_migration) { - NinjaMailerJob::dispatch($nmo, true); - } - - return response()->json([ - '_id' => Str::uuid(), - 'method' => config('queue.default'), - 'started_at' => now(), - ], 200); - } - - // If there's existing company and force ** is provided ** - purge the company and migrate again. - if ($checks['existing_company'] == true && $checks['force'] == true) { - nlog('purging the existing company here'); - $this->purgeCompanyWithForceFlag($existing_company); - - $account = auth()->user()->account; - $fresh_company = (new ImportMigrations())->getCompany($account); - $fresh_company->is_disabled = true; - $fresh_company->save(); - - $account->default_company_id = $fresh_company->id; - $account->save(); - - $fresh_company_token = new CompanyToken(); - $fresh_company_token->user_id = $user->id; - $fresh_company_token->company_id = $fresh_company->id; - $fresh_company_token->account_id = $account->id; - $fresh_company_token->name = $request->token_name ?? Str::random(12); - $fresh_company_token->token = $request->token ?? Str::random(64); - $fresh_company_token->is_system = true; - $fresh_company_token->save(); - - /** @var \App\Models\User $user */ - $user->companies()->attach($fresh_company->id, [ - 'account_id' => $account->id, - 'is_owner' => 1, - 'is_admin' => 1, - 'is_locked' => 0, - 'notifications' => CompanySettings::notificationDefaults(), - 'permissions' => '', - 'settings' => null, - ]); - } - - // If there's no existing company migrate just normally. - if ($checks['existing_company'] == false) { - nlog('creating fresh company'); - - $account = auth()->user()->account; - $fresh_company = (new ImportMigrations())->getCompany($account); - - $fresh_company->is_disabled = true; - $fresh_company->save(); - - $fresh_company_token = new CompanyToken(); - $fresh_company_token->user_id = $user->id; - $fresh_company_token->company_id = $fresh_company->id; - $fresh_company_token->account_id = $account->id; - $fresh_company_token->name = $request->token_name ?? Str::random(12); - $fresh_company_token->token = $request->token ?? Str::random(64); - $fresh_company_token->is_system = true; - - $fresh_company_token->save(); - - /** @var \App\Models\User $user */ - $user->companies()->attach($fresh_company->id, [ - 'account_id' => $account->id, - 'is_owner' => 1, - 'is_admin' => 1, - 'is_locked' => 0, - 'notifications' => CompanySettings::notificationDefaults(), - 'permissions' => '', - 'settings' => null, - ]); - } - - $migration_file = $request->file($company['company_index']) - ->storeAs( - 'migrations', - $request->file($company['company_index'])->getClientOriginalName(), - 'public' - ); - - if (app()->environment() == 'testing') { - nlog('environment is testing = bailing out now'); - - return; - } - - nlog('starting migration job'); - nlog($migration_file); - - if (Ninja::isHosted()) { - StartMigration::dispatch($migration_file, $user, $fresh_company, $this->silent_migration)->onQueue('migration'); - } else { - StartMigration::dispatch($migration_file, $user, $fresh_company, $this->silent_migration); - } + foreach ($companies as $company) { + if (! is_array($company)) { + continue; } - return response()->json([ - '_id' => Str::uuid(), - 'method' => config('queue.default'), - 'started_at' => now(), - ], 200); + $company = (array) $company; + $user = auth()->user(); + + $company_count = $user->account->companies()->count(); + $fresh_company = false; + + // Look for possible existing company (based on company keys). + $existing_company = Company::query()->whereRaw('BINARY `company_key` = ?', [$company['company_key']])->first(); + + App::forgetInstance('translator'); + $t = app('translator'); + $t->replace(Ninja::transformTranslations($user->account->companies()->first()->settings)); + App::setLocale($user->account->companies()->first()->getLocale()); + + if (! $existing_company && $company_count >= 10) { + $nmo = new NinjaMailerObject(); + $nmo->mailable = new MaxCompanies($user->account->companies()->first()); + $nmo->company = $user->account->companies()->first(); + $nmo->settings = $user->account->companies()->first()->settings; + $nmo->to_user = $user; + + if(!$this->silent_migration) { + NinjaMailerJob::dispatch($nmo, true); + } + + return; + } elseif ($existing_company && $company_count > 10) { + $nmo = new NinjaMailerObject(); + $nmo->mailable = new MaxCompanies($user->account->companies()->first()); + $nmo->company = $user->account->companies()->first(); + $nmo->settings = $user->account->companies()->first()->settings; + $nmo->to_user = $user; + + if(!$this->silent_migration) { + NinjaMailerJob::dispatch($nmo, true); + } + + return; + } + + $checks = [ + 'existing_company' => $existing_company ? (bool) 1 : false, + 'force' => array_key_exists('force', $company) ? (bool) $company['force'] : false, + ]; + + // If there's existing company and ** no ** force is provided - skip migration. + if ($checks['existing_company'] == true && $checks['force'] == false) { + nlog('Migrating: Existing company without force. (CASE_01)'); + + $nmo = new NinjaMailerObject(); + $nmo->mailable = new ExistingMigration($existing_company); + $nmo->company = $user->account->companies()->first(); + $nmo->settings = $user->account->companies()->first(); + $nmo->to_user = $user; + + if(!$this->silent_migration) { + NinjaMailerJob::dispatch($nmo, true); + } + + return response()->json([ + '_id' => Str::uuid(), + 'method' => config('queue.default'), + 'started_at' => now(), + ], 200); + } + + // If there's existing company and force ** is provided ** - purge the company and migrate again. + if ($checks['existing_company'] == true && $checks['force'] == true) { + nlog('purging the existing company here'); + $this->purgeCompanyWithForceFlag($existing_company); + + $account = auth()->user()->account; + $fresh_company = (new ImportMigrations())->getCompany($account); + $fresh_company->is_disabled = true; + $fresh_company->save(); + + $account->default_company_id = $fresh_company->id; + $account->save(); + + $fresh_company_token = new CompanyToken(); + $fresh_company_token->user_id = $user->id; + $fresh_company_token->company_id = $fresh_company->id; + $fresh_company_token->account_id = $account->id; + $fresh_company_token->name = $request->token_name ?? Str::random(12); + $fresh_company_token->token = $request->token ?? Str::random(64); + $fresh_company_token->is_system = true; + $fresh_company_token->save(); + + /** @var \App\Models\User $user */ + $user->companies()->attach($fresh_company->id, [ + 'account_id' => $account->id, + 'is_owner' => 1, + 'is_admin' => 1, + 'is_locked' => 0, + 'notifications' => CompanySettings::notificationDefaults(), + 'permissions' => '', + 'settings' => null, + ]); + } + + // If there's no existing company migrate just normally. + if ($checks['existing_company'] == false) { + nlog('creating fresh company'); + + $account = auth()->user()->account; + $fresh_company = (new ImportMigrations())->getCompany($account); + + $fresh_company->is_disabled = true; + $fresh_company->save(); + + $fresh_company_token = new CompanyToken(); + $fresh_company_token->user_id = $user->id; + $fresh_company_token->company_id = $fresh_company->id; + $fresh_company_token->account_id = $account->id; + $fresh_company_token->name = $request->token_name ?? Str::random(12); + $fresh_company_token->token = $request->token ?? Str::random(64); + $fresh_company_token->is_system = true; + + $fresh_company_token->save(); + + /** @var \App\Models\User $user */ + $user->companies()->attach($fresh_company->id, [ + 'account_id' => $account->id, + 'is_owner' => 1, + 'is_admin' => 1, + 'is_locked' => 0, + 'notifications' => CompanySettings::notificationDefaults(), + 'permissions' => '', + 'settings' => null, + ]); + } + + $migration_file = $request->file($company['company_index']) + ->storeAs( + 'migrations', + $request->file($company['company_index'])->getClientOriginalName(), + 'public' + ); + + if (app()->environment() == 'testing') { + nlog('environment is testing = bailing out now'); + + return; + } + + nlog('starting migration job'); + nlog($migration_file); + + if (Ninja::isHosted()) { + StartMigration::dispatch($migration_file, $user, $fresh_company, $this->silent_migration)->onQueue('migration'); + } else { + StartMigration::dispatch($migration_file, $user, $fresh_company, $this->silent_migration); + } } + return response()->json([ + '_id' => Str::uuid(), + 'method' => config('queue.default'), + 'started_at' => now(), + ], 200); + } } diff --git a/app/Http/Controllers/OneTimeTokenController.php b/app/Http/Controllers/OneTimeTokenController.php index 6e3f54f2e914..1d4773b530c5 100644 --- a/app/Http/Controllers/OneTimeTokenController.php +++ b/app/Http/Controllers/OneTimeTokenController.php @@ -22,8 +22,6 @@ use Illuminate\Support\Str; class OneTimeTokenController extends BaseController { - private $contexts = [ - ]; public function __construct() { diff --git a/app/Http/Controllers/PostMarkController.php b/app/Http/Controllers/PostMarkController.php index ec8a481c382e..e2974f99831b 100644 --- a/app/Http/Controllers/PostMarkController.php +++ b/app/Http/Controllers/PostMarkController.php @@ -19,7 +19,6 @@ use Illuminate\Http\Request; */ class PostMarkController extends BaseController { - private $invitation; public function __construct() { diff --git a/app/Http/Controllers/PreviewPurchaseOrderController.php b/app/Http/Controllers/PreviewPurchaseOrderController.php index d6279868223b..ef1ef40d7f66 100644 --- a/app/Http/Controllers/PreviewPurchaseOrderController.php +++ b/app/Http/Controllers/PreviewPurchaseOrderController.php @@ -219,139 +219,6 @@ class PreviewPurchaseOrderController extends BaseController } - public function livex(PreviewPurchaseOrderRequest $request) - { - /** @var \App\Models\User $user */ - $user = auth()->user(); - $company = $user->company(); - $file_path = (new PreviewPdf('', $company))->handle(); - $response = Response::make($file_path, 200); - $response->header('Content-Type', 'application/pdf'); - - return $response; - - MultiDB::setDb($company->db); - - $repo = new PurchaseOrderRepository(); - $entity_obj = PurchaseOrderFactory::create($company->id, $user->id); - $class = PurchaseOrder::class; - - try { - DB::connection(config('database.default'))->beginTransaction(); - - if ($request->has('entity_id')) { - /** @var \App\Models\PurchaseOrder|\Illuminate\Contracts\Database\Eloquent\Builder $entity_obj **/ - $entity_obj = \App\Models\PurchaseOrder::on(config('database.default')) - ->with('vendor.company') - ->where('id', $this->decodePrimaryKey($request->input('entity_id'))) - ->where('company_id', $company->id) - ->withTrashed() - ->first(); - } - - $entity_obj = $repo->save($request->all(), $entity_obj); - - if (!$request->has('entity_id')) { - $entity_obj->service()->fillDefaults()->save(); - } - - App::forgetInstance('translator'); - $t = app('translator'); - App::setLocale($entity_obj->company->locale()); - $t->replace(Ninja::transformTranslations($entity_obj->company->settings)); - - $html = new VendorHtmlEngine($entity_obj->invitations()->first()); - - /** @var \App\Models\Design $design */ - $design = \App\Models\Design::withTrashed()->find($entity_obj->design_id); - - /* Catch all in case migration doesn't pass back a valid design */ - if (!$design) { - $design = \App\Models\Design::find(2); - } - - if ($design->is_custom) { - $options = [ - 'custom_partials' => json_decode(json_encode($design->design), true) - ]; - $template = new PdfMakerDesign(PdfDesignModel::CUSTOM, $options); - } else { - $template = new PdfMakerDesign(strtolower($design->name)); - } - - $variables = $html->generateLabelsAndValues(); - - $state = [ - 'template' => $template->elements([ - 'client' => null, - 'vendor' => $entity_obj->vendor, - 'entity' => $entity_obj, - 'pdf_variables' => (array) $entity_obj->company->settings->pdf_variables, - 'variables' => $html->generateLabelsAndValues(), - '$product' => $design->design->product, - ]), - 'variables' => $html->generateLabelsAndValues(), - 'options' => [ - 'client' => null, - 'vendor' => $entity_obj->vendor, - 'purchase_orders' => [$entity_obj], - 'variables' => $html->generateLabelsAndValues(), - ], - 'process_markdown' => $entity_obj->company->markdown_enabled, - ]; - - $maker = new PdfMaker($state); - - $maker - ->design($template) - ->build(); - - DB::connection(config('database.default'))->rollBack(); - - if (request()->query('html') == 'true') { - return $maker->getCompiledHTML(); - } - } catch(\Exception $e) { - DB::connection(config('database.default'))->rollBack(); - return; - } - - /** @var \App\Models\User $user */ - $user = auth()->user(); - - //if phantom js...... inject here.. - if (config('ninja.phantomjs_pdf_generation') || config('ninja.pdf_generator') == 'phantom') { - return (new Phantom())->convertHtmlToPdf($maker->getCompiledHTML(true)); - } - - if (config('ninja.invoiceninja_hosted_pdf_generation') || config('ninja.pdf_generator') == 'hosted_ninja') { - $pdf = (new NinjaPdf())->build($maker->getCompiledHTML(true)); - - $numbered_pdf = $this->pageNumbering($pdf, $user->company()); - - if ($numbered_pdf) { - $pdf = $numbered_pdf; - } - - return $pdf; - } - - $file_path = (new PreviewPdf($maker->getCompiledHTML(true), $company))->handle(); - - - if (Ninja::isHosted()) { - LightLogs::create(new LivePreview()) - ->increment() - ->batch(); - } - - - $response = Response::make($file_path, 200); - $response->header('Content-Type', 'application/pdf'); - - return $response; - } - private function blankEntity() { /** @var \App\Models\User $user */ diff --git a/app/Http/Controllers/ProtectedDownloadController.php b/app/Http/Controllers/ProtectedDownloadController.php index ee5fc984ce7a..b578938d33b3 100644 --- a/app/Http/Controllers/ProtectedDownloadController.php +++ b/app/Http/Controllers/ProtectedDownloadController.php @@ -25,7 +25,6 @@ class ProtectedDownloadController extends BaseController if (!$hashed_path) { throw new SystemError('File no longer available', 404); - abort(404, 'File no longer available'); } return response()->streamDownload(function () use ($hashed_path) { diff --git a/app/Http/Controllers/PurchaseOrderController.php b/app/Http/Controllers/PurchaseOrderController.php index 8fc2228d492f..c06fff041bd2 100644 --- a/app/Http/Controllers/PurchaseOrderController.php +++ b/app/Http/Controllers/PurchaseOrderController.php @@ -717,7 +717,7 @@ class PurchaseOrderController extends BaseController default: return response()->json(['message' => ctrans('texts.action_unavailable', ['action' => $action])], 400); - break; + } } diff --git a/app/Http/Controllers/QuoteController.php b/app/Http/Controllers/QuoteController.php index 38c5ba2d2ba5..c96733d073e0 100644 --- a/app/Http/Controllers/QuoteController.php +++ b/app/Http/Controllers/QuoteController.php @@ -787,7 +787,6 @@ class QuoteController extends BaseController break; default: return response()->json(['message' => ctrans('texts.action_unavailable', ['action' => $action])], 400); - break; } } diff --git a/app/Http/Controllers/SetupController.php b/app/Http/Controllers/SetupController.php index f30831855c76..7c91dc91a019 100644 --- a/app/Http/Controllers/SetupController.php +++ b/app/Http/Controllers/SetupController.php @@ -234,24 +234,6 @@ class SetupController extends Controller } } - private function testPhantom() - { - try { - $key = config('ninja.phantomjs_key'); - $url = 'https://www.invoiceninja.org/'; - - $phantom_url = "https://phantomjscloud.com/api/browser/v2/{$key}/?request=%7Burl:%22{$url}%22,renderType:%22pdf%22%7D"; - $pdf = CurlUtils::get($phantom_url); - - Storage::disk(config('filesystems.default'))->put('test.pdf', $pdf); - Storage::disk('local')->put('test.pdf', $pdf); - - return response(['url' => Storage::disk('local')->url('test.pdf')], 200); - } catch (Exception $e) { - return response([], 500); - } - } - public function clearCompiledCache() { $cacheCompiled = base_path('bootstrap/cache/compiled.php'); diff --git a/app/Http/Middleware/PasswordProtection.php b/app/Http/Middleware/PasswordProtection.php index 9c8a38c52f10..a07cd1aea353 100644 --- a/app/Http/Middleware/PasswordProtection.php +++ b/app/Http/Middleware/PasswordProtection.php @@ -61,7 +61,7 @@ class PasswordProtection return $next($request); } elseif(strlen(auth()->user()->oauth_provider_id) > 2 && !auth()->user()->company()->oauth_password_required) { return $next($request); - } elseif ($request->header('X-API-OAUTH-PASSWORD') && strlen($request->header('X-API-OAUTH-PASSWORD')) >= 1) { + } elseif ($request->header('X-API-OAUTH-PASSWORD') && strlen($request->header('X-API-OAUTH-PASSWORD')) > 1) { //user is attempting to reauth with OAuth - check the token value //todo expand this to include all OAuth providers if (auth()->user()->oauth_provider_id == 'google') { diff --git a/app/Http/Requests/Client/StoreClientRequest.php b/app/Http/Requests/Client/StoreClientRequest.php index f1d4c84518f4..8592d93f2e3a 100644 --- a/app/Http/Requests/Client/StoreClientRequest.php +++ b/app/Http/Requests/Client/StoreClientRequest.php @@ -185,48 +185,44 @@ class StoreClientRequest extends Request ]; } - private function getLanguageId($language_code) + private function getLanguageId(string $language_code) { - $languages = Cache::get('languages'); + /** @var \Illuminate\Support\Collection<\App\Models\Language> */ + $languages = app('languages'); - $language = $languages->filter(function ($item) use ($language_code) { + $language = $languages->first(function ($item) use ($language_code) { return $item->locale == $language_code; - })->first(); + }); - if ($language) { - return (string) $language->id; - } + return $language ? (string)$language->id : ''; - return ''; } - private function getCountryCode($country_code) + private function getCountryCode(string $country_code) { - $countries = Cache::get('countries'); + + /** @var \Illuminate\Support\Collection<\App\Models\Country> */ + $countries = app('countries'); - $country = $countries->filter(function ($item) use ($country_code) { + $country = $countries->first(function ($item) use ($country_code) { return $item->iso_3166_2 == $country_code || $item->iso_3166_3 == $country_code; - })->first(); + }); - if ($country) { - return (string) $country->id; - } - - return ''; + return $country ? (string) $country->id : ''; + } private function getCurrencyCode($code) { - $currencies = Cache::get('currencies'); + + /** @var \Illuminate\Support\Collection<\App\Models\Currency> */ + $currencies = app('currencies'); - $currency = $currencies->filter(function ($item) use ($code) { + $currency = $currencies->first(function ($item) use ($code) { return $item->code == $code; - })->first(); + }); - if ($currency) { - return (string) $currency->id; - } - - return ''; + return $currency ? (string)$currency->id : ''; + } } diff --git a/app/Http/Requests/Client/UpdateClientRequest.php b/app/Http/Requests/Client/UpdateClientRequest.php index 1378b239ed41..8933954de922 100644 --- a/app/Http/Requests/Client/UpdateClientRequest.php +++ b/app/Http/Requests/Client/UpdateClientRequest.php @@ -139,32 +139,28 @@ class UpdateClientRequest extends Request private function getCountryCode($country_code) { - $countries = Cache::get('countries'); + + /** @var \Illuminate\Support\Collection<\App\Models\Country> */ + $countries = app('countries'); - $country = $countries->filter(function ($item) use ($country_code) { + $country = $countries->first(function ($item) use ($country_code) { return $item->iso_3166_2 == $country_code || $item->iso_3166_3 == $country_code; - })->first(); + }); - if ($country) { - return (string) $country->id; - } - - return ''; + return $country ? (string) $country->id : ''; } private function getLanguageId($language_code) { - $languages = Cache::get('languages'); + + /** @var \Illuminate\Support\Collection<\App\Models\Language> */ + $languages = app('languages'); - $language = $languages->filter(function ($item) use ($language_code) { + $language = $languages->first(function ($item) use ($language_code) { return $item->locale == $language_code; - })->first(); + }); - if ($language) { - return (string) $language->id; - } - - return ''; + return $language ? (string) $language->id : ''; } /** diff --git a/app/Http/Requests/Payment/StorePaymentRequest.php b/app/Http/Requests/Payment/StorePaymentRequest.php index f3e8e33adfe8..34bba9f648af 100644 --- a/app/Http/Requests/Payment/StorePaymentRequest.php +++ b/app/Http/Requests/Payment/StorePaymentRequest.php @@ -130,7 +130,7 @@ class StorePaymentRequest extends Request } if (! isset($input['idempotency_key'])) { - $input['idempotency_key'] = substr(sha1(json_encode($input)).time()."{$input['date']}{$input['amount']}{$user->id}", 0, 64); + $input['idempotency_key'] = substr(time()."{$input['date']}{$input['amount']}{$credits_total}{$this->client_id}{$user->company()->company_key}", 0, 64); } $this->replace($input); diff --git a/app/Http/Requests/Preview/PreviewInvoiceRequest.php b/app/Http/Requests/Preview/PreviewInvoiceRequest.php index 2c8cc682f953..4a8d82e57b15 100644 --- a/app/Http/Requests/Preview/PreviewInvoiceRequest.php +++ b/app/Http/Requests/Preview/PreviewInvoiceRequest.php @@ -88,7 +88,8 @@ class PreviewInvoiceRequest extends Request public function resolveInvitation() { $invitation = false; - + + /** @phpstan-ignore-next-line */ if(! $this->entity_id ?? false) { return $this->stubInvitation(); } @@ -98,6 +99,7 @@ class PreviewInvoiceRequest extends Request 'quote' => $invitation = QuoteInvitation::withTrashed()->where('quote_id', $this->entity_id)->first(), 'credit' => $invitation = CreditInvitation::withTrashed()->where('credit_id', $this->entity_id)->first(), 'recurring_invoice' => $invitation = RecurringInvoiceInvitation::withTrashed()->where('recurring_invoice_id', $this->entity_id)->first(), + default => $invitation = false, }; if($invitation) { diff --git a/app/Http/Requests/Shop/StoreShopClientRequest.php b/app/Http/Requests/Shop/StoreShopClientRequest.php index a41c4e26d099..3dc6e78d3cbf 100644 --- a/app/Http/Requests/Shop/StoreShopClientRequest.php +++ b/app/Http/Requests/Shop/StoreShopClientRequest.php @@ -155,23 +155,27 @@ class StoreShopClientRequest extends Request private function getCountryCode($country_code) { - $countries = Cache::get('countries'); + + /** @var \Illuminate\Support\Collection<\App\Models\Country> */ + $countries = app('countries'); - $country = $countries->filter(function ($item) use ($country_code) { + $country = $countries->first(function ($item) use ($country_code) { return $item->iso_3166_2 == $country_code || $item->iso_3166_3 == $country_code; - })->first(); + }); - return (string) $country->id; + return $country ? (string) $country->id : ''; } private function getCurrencyCode($code) { - $currencies = Cache::get('currencies'); + + /** @var \Illuminate\Support\Collection<\App\Models\Country> */ + $currencies = app('currencies'); - $currency = $currencies->filter(function ($item) use ($code) { + $currency = $currencies->first(function ($item) use ($code) { return $item->code == $code; - })->first(); + }); - return (string) $currency->id; + return $currency ? (string) $currency->id : ''; } } diff --git a/app/Import/Transformer/BaseTransformer.php b/app/Import/Transformer/BaseTransformer.php index 32a333f66e98..2dc91e6c2f47 100644 --- a/app/Import/Transformer/BaseTransformer.php +++ b/app/Import/Transformer/BaseTransformer.php @@ -119,17 +119,18 @@ class BaseTransformer { $code = array_key_exists($key, $data) ? $data[$key] : false; - $currencies = Cache::get('currencies'); + if(!$code) + return $this->company->settings->currency_id; - $currency = $currencies - ->filter(function ($item) use ($code) { - return $item->code == $code; - }) - ->first(); + /** @var \Illuminate\Support\Collection<\App\Models\Currency> */ + $currencies = app('currencies'); + + $currency = $currencies->first(function ($item) use ($code) { + return $item->code == $code; + }); + + return $currency ? (string) $currency->id : $this->company->settings->currency_id; - return $currency - ? $currency->id - : $this->company->settings->currency_id; } public function getFrequency($frequency = RecurringInvoice::FREQUENCY_MONTHLY): int @@ -653,12 +654,11 @@ class BaseTransformer /** * @param $name * - * @return int|null + * @return int */ public function getExpenseCategoryId($name) { - /** @var \App\Models\ExpenseCategory $ec */ - + /** @var ?\App\Models\ExpenseCategory $ec */ $ec = ExpenseCategory::query()->where('company_id', $this->company->id) ->where('is_deleted', false) ->whereRaw("LOWER(REPLACE(`name`, ' ' ,'')) = ?", [ @@ -674,7 +674,7 @@ class BaseTransformer $ec->name = $name; $ec->save(); - return $ec ? $ec->id : null; + return $ec->id; } public function getOrCreateExpenseCategry($name) diff --git a/app/Import/Transformer/Invoice2Go/InvoiceTransformer.php b/app/Import/Transformer/Invoice2Go/InvoiceTransformer.php index cf7771d63740..28d8d530aa44 100644 --- a/app/Import/Transformer/Invoice2Go/InvoiceTransformer.php +++ b/app/Import/Transformer/Invoice2Go/InvoiceTransformer.php @@ -277,7 +277,7 @@ class InvoiceTransformer extends BaseTransformer if($key == 0) { continue; } - + /** @var array $row */ if(is_array($row[5])) { $csv = str_getcsv($row[5][0], ";"); $row[5] = array_combine(explode(",", $csv[0]), explode(",", $csv[1])); diff --git a/app/Import/Transformer/Wave/InvoiceTransformer.php b/app/Import/Transformer/Wave/InvoiceTransformer.php index c1d5df1e4031..8908a5c0cf0d 100644 --- a/app/Import/Transformer/Wave/InvoiceTransformer.php +++ b/app/Import/Transformer/Wave/InvoiceTransformer.php @@ -50,7 +50,7 @@ class InvoiceTransformer extends BaseTransformer 'client_id' => $this->getClient($customer_name = $this->getString($invoice_data, $customer_key), null), 'number' => $invoice_number = $this->getString($invoice_data, 'Invoice Number'), 'date' => $this->parseDate($invoice_data[$date_key]) ?: now()->format('Y-m-d'), //27-01-2022 - 'currency_id' => $this->getCurrencyByCode($invoice_data, 'Currency'), + // 'currency_id' => $this->getCurrencyByCode($invoice_data, 'Currency'), 'status_id' => Invoice::STATUS_SENT, 'due_date' => array_key_exists('Due Date', $invoice_data) ? $this->parseDate($invoice_data['Due Date']) : null, ]; diff --git a/app/Jobs/Company/CompanyImport.php b/app/Jobs/Company/CompanyImport.php index f52ce435b5b9..9108998985c3 100644 --- a/app/Jobs/Company/CompanyImport.php +++ b/app/Jobs/Company/CompanyImport.php @@ -1205,6 +1205,7 @@ class CompanyImport implements ShouldQueue continue; } + /** @var string $storage_url */ $storage_url = (object)$this->getObject('storage_url', true); if (!Storage::exists($document->url) && is_string($storage_url)) { @@ -1351,45 +1352,31 @@ class CompanyImport implements ShouldQueue switch ($type) { case Company::class: return $this->company->id; - break; case Client::class: return $this->transformId('clients', $id); - break; case ClientContact::class: return $this->transformId('client_contacts', $id); - break; case Credit::class: return $this->transformId('credits', $id); - break; case Expense::class: return $this->transformId('expenses', $id); - break; case 'invoices': return $this->transformId('invoices', $id); - break; case Payment::class: return $this->transformId('payments', $id); - break; case Project::class: return $this->transformId('projects', $id); - break; case Product::class: return $this->transformId('products', $id); - break; case Quote::class: return $this->transformId('quotes', $id); - break; case RecurringInvoice::class: return $this->transformId('recurring_invoices', $id); - break; case Company::class: return $this->transformId('clients', $id); - break; - default: return false; - break; } } @@ -1420,10 +1407,10 @@ class CompanyImport implements ShouldQueue switch ($type) { case 'invoices': return $this->transformId('invoices', $id); - break; + case Credit::class: return $this->transformId('credits', $id); - break; + case Payment::class: return $this->transformId('payments', $id); default: diff --git a/app/Jobs/Cron/SubscriptionCron.php b/app/Jobs/Cron/SubscriptionCron.php index 1c4b7dbc16ad..b3ddbb3e7e32 100644 --- a/app/Jobs/Cron/SubscriptionCron.php +++ b/app/Jobs/Cron/SubscriptionCron.php @@ -65,9 +65,9 @@ class SubscriptionCron //Requires the crons to be updated and set to hourly @ 00:01 private function timezoneAware() { - $grouped_company_ids = - - Invoice::select('company_id') + + Invoice::query() + ->with('company') ->where('is_deleted', 0) ->whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL]) ->where('balance', '>', 0) @@ -77,10 +77,11 @@ class SubscriptionCron ->whereNotNull('subscription_id') ->groupBy('company_id') ->cursor() - ->each(function ($company_id) { + ->each(function ($invoice) { /** @var \App\Models\Company $company */ - $company = Company::find($company_id); + // $company = Company::find($invoice->company_id); + $company = $invoice->company; $timezone_now = now()->setTimezone($company->timezone()->name ?? 'Pacific/Midway'); diff --git a/app/Jobs/Entity/CreateRawPdf.php b/app/Jobs/Entity/CreateRawPdf.php index aa10bdf019d9..4d1936c85fdc 100644 --- a/app/Jobs/Entity/CreateRawPdf.php +++ b/app/Jobs/Entity/CreateRawPdf.php @@ -40,7 +40,7 @@ class CreateRawPdf public Invoice | Credit | Quote | RecurringInvoice | PurchaseOrder $entity; - public $company; + public \App\Models\Company $company; public $contact; @@ -55,6 +55,7 @@ class CreateRawPdf { $this->invitation = $invitation; + $this->company = $invitation->company; if ($invitation instanceof InvoiceInvitation) { $this->entity = $invitation->invoice; @@ -115,7 +116,14 @@ class CreateRawPdf } if ($this->entity_string == "invoice" && $this->entity->client->getSetting("merge_e_invoice_to_pdf")) { $pdf = (new MergeEDocument($this->entity, $pdf))->handle(); + } + + $merge_docs = $this->entity->client ? $this->entity->client->getSetting('embed_documents') : $this->company->getSetting('embed_documents'); + + if($merge_docs && ($this->entity->documents()->where('is_public', true)->count() > 0 || $this->company->documents()->where('is_public', true)->count() > 0)) { + $pdf = $this->entity->documentMerge($pdf); } + return $pdf; } diff --git a/app/Jobs/Invoice/CreateUbl.php b/app/Jobs/Invoice/CreateUbl.php index 167018736f7e..cd018b4ed965 100644 --- a/app/Jobs/Invoice/CreateUbl.php +++ b/app/Jobs/Invoice/CreateUbl.php @@ -192,7 +192,7 @@ class CreateUbl implements ShouldQueue /** * @param $item * @param $invoice_total - * @return float|int + * @return float */ private function getItemTaxable($item, $invoice_total) { diff --git a/app/Jobs/Ninja/TaskScheduler.php b/app/Jobs/Ninja/TaskScheduler.php index a2c8acf14a16..62f2a011d78a 100644 --- a/app/Jobs/Ninja/TaskScheduler.php +++ b/app/Jobs/Ninja/TaskScheduler.php @@ -63,7 +63,7 @@ class TaskScheduler implements ShouldQueue //@var \App\Models\Schedule $scheduler $scheduler->service()->runTask(); } catch(\Exception $e) { - nlog($e->getMessage()); + nlog("Exception:: TaskScheduler:: Doing job {$scheduler->name}" . $e->getMessage()); } }); diff --git a/app/Jobs/Util/Import.php b/app/Jobs/Util/Import.php index 91d06f2b49be..696b37bee891 100644 --- a/app/Jobs/Util/Import.php +++ b/app/Jobs/Util/Import.php @@ -1455,30 +1455,23 @@ class Import implements ShouldQueue switch ($status_id) { case 1: return $payment; - break; case 2: return $payment->service()->deletePayment(); - break; case 3: return $payment->service()->deletePayment(); - break; case 4: return $payment; - break; case 5: $payment->status_id = Payment::STATUS_PARTIALLY_REFUNDED; $payment->save(); return $payment; - break; case 6: $payment->status_id = Payment::STATUS_REFUNDED; $payment->save(); return $payment; - break; default: return $payment; - break; } } diff --git a/app/Jobs/Vendor/CreatePurchaseOrderPdf.php b/app/Jobs/Vendor/CreatePurchaseOrderPdf.php index 01ced2acba33..824ac6424f5b 100644 --- a/app/Jobs/Vendor/CreatePurchaseOrderPdf.php +++ b/app/Jobs/Vendor/CreatePurchaseOrderPdf.php @@ -100,18 +100,6 @@ class CreatePurchaseOrderPdf implements ShouldQueue return $ps->boot()->getPdf(); - - $pdf = $this->rawPdf(); - - if ($pdf) { - try { - Storage::disk($this->disk)->put($this->file_path, $pdf); - } catch(\Exception $e) { - throw new FilePermissionsFailure($e->getMessage()); - } - } - - return $this->file_path; } public function rawPdf() diff --git a/app/Libraries/OAuth/OAuth.php b/app/Libraries/OAuth/OAuth.php index 9fef9bc3ab3b..e834d0628b1e 100644 --- a/app/Libraries/OAuth/OAuth.php +++ b/app/Libraries/OAuth/OAuth.php @@ -130,7 +130,6 @@ class OAuth return $this; default: return null; - break; } } diff --git a/app/Livewire/BillingPortal/Authentication/RegisterOrLogin.php b/app/Livewire/BillingPortal/Authentication/RegisterOrLogin.php index 100d1e6e174a..559ad798d1b9 100644 --- a/app/Livewire/BillingPortal/Authentication/RegisterOrLogin.php +++ b/app/Livewire/BillingPortal/Authentication/RegisterOrLogin.php @@ -256,7 +256,9 @@ class RegisterOrLogin extends Component public function render() { - $countries = Cache::get('countries'); + + /** @var \Illuminate\Support\Collection<\App\Models\Country> */ + $countries = app('countries'); return view('billing-portal.v3.authentication.register-or-login', [ 'countries' => $countries, diff --git a/app/Livewire/BillingPortalPurchase.php b/app/Livewire/BillingPortalPurchase.php index d59e5e4789fe..0a15710018c6 100644 --- a/app/Livewire/BillingPortalPurchase.php +++ b/app/Livewire/BillingPortalPurchase.php @@ -281,17 +281,25 @@ class BillingPortalPurchase extends Component } if (array_key_exists('currency_id', $this->request_data)) { - $currency = Cache::get('currencies')->filter(function ($item) { + + /** @var \Illuminate\Support\Collection<\App\Models\Currency> */ + $currencies = app('currencies'); + + $currency = $currencies->first(function ($item) { return $item->id == $this->request_data['currency_id']; - })->first(); + }); if ($currency) { $data['settings']->currency_id = $currency->id; } } elseif ($this->subscription->group_settings && property_exists($this->subscription->group_settings->settings, 'currency_id')) { - $currency = Cache::get('currencies')->filter(function ($item) { + + /** @var \Illuminate\Support\Collection<\App\Models\Currency> */ + $currencies = app('currencies'); + + $currency = $currencies->first(function ($item) { return $item->id == $this->subscription->group_settings->settings->currency_id; - })->first(); + }); if ($currency) { $data['settings']->currency_id = $currency->id; @@ -300,10 +308,12 @@ class BillingPortalPurchase extends Component if (array_key_exists('locale', $this->request_data)) { $request = $this->request_data; - - $record = Cache::get('languages')->filter(function ($item) use ($request) { + + /** @var \Illuminate\Support\Collection<\App\Models\Language> */ + $languages = app('languages'); + $record = $languages->first(function ($item) use ($request) { return $item->locale == $request['locale']; - })->first(); + }); if ($record) { $data['settings']['language_id'] = (string)$record->id; diff --git a/app/Livewire/BillingPortalPurchasev2.php b/app/Livewire/BillingPortalPurchasev2.php index 0bdab5de77d5..d707707578b2 100644 --- a/app/Livewire/BillingPortalPurchasev2.php +++ b/app/Livewire/BillingPortalPurchasev2.php @@ -676,17 +676,25 @@ class BillingPortalPurchasev2 extends Component } if (array_key_exists('currency_id', $this->request_data)) { - $currency = Cache::get('currencies')->filter(function ($item) { + + /** @var \Illuminate\Support\Collection<\App\Models\Currency> */ + $currencies = app('currencies'); + + $currency = $currencies->first(function ($item) { return $item->id == $this->request_data['currency_id']; - })->first(); + }); if ($currency) { $data['settings']->currency_id = $currency->id; } } elseif ($this->subscription->group_settings && property_exists($this->subscription->group_settings->settings, 'currency_id')) { - $currency = Cache::get('currencies')->filter(function ($item) { + + /** @var \Illuminate\Support\Collection<\App\Models\Currency> */ + $currencies = app('currencies'); + + $currency = $currencies->first(function ($item) { return $item->id == $this->subscription->group_settings->settings->currency_id; - })->first(); + }); if ($currency) { $data['settings']->currency_id = $currency->id; @@ -696,9 +704,12 @@ class BillingPortalPurchasev2 extends Component if (array_key_exists('locale', $this->request_data)) { $request = $this->request_data; - $record = Cache::get('languages')->filter(function ($item) use ($request) { + /** @var \Illuminate\Support\Collection<\App\Models\Language> */ + $languages = app('languages'); + + $record = $languages->first(function ($item) use ($request) { return $item->locale == $request['locale']; - })->first(); + }); if ($record) { $data['settings']['language_id'] = (string)$record->id; diff --git a/app/Mail/Engine/PaymentEmailEngine.php b/app/Mail/Engine/PaymentEmailEngine.php index 7fee5173eba3..26ee0ae33386 100644 --- a/app/Mail/Engine/PaymentEmailEngine.php +++ b/app/Mail/Engine/PaymentEmailEngine.php @@ -516,14 +516,5 @@ class PaymentEmailEngine extends BaseEmailEngine '; - return ' -
- '. $text .' - | -
- '. $text .' - | -
+ // '. $text .' + // | + //
- '. $text .' - | -
+ // '. $text .' + // | + //
You have certain recourse rights if any debit does not comply with this agreement. For example, you have the right to receive reimbursement for any debit that is not authorized or is not consistent with this PAD Agreement. To obtain more information on your recourse rights, contact your financial institution.
You may amend or cancel this authorization at any time by providing the merchant with thirty (30) days notice at {{ $company->present()->email() }}. To obtain a sample cancellation form, or further information on cancelling a PAD agreement, please contact your financial institution.
+You may amend or cancel this authorization at any time by providing the merchant with thirty (30) days notice at {{ $company->owner()->email }}. To obtain a sample cancellation form, or further information on cancelling a PAD agreement, please contact your financial institution.
{{ $company->present()->name() }} partners with Stripe to provide payment processing.
diff --git a/tests/Feature/CreditTest.php b/tests/Feature/CreditTest.php index 28aba2164bda..40e4409e08f0 100644 --- a/tests/Feature/CreditTest.php +++ b/tests/Feature/CreditTest.php @@ -43,6 +43,102 @@ class CreditTest extends TestCase $this->makeTestData(); } + public function testPaidToDateAdjustments() + { + + $c = Client::factory()->create([ + 'company_id' => $this->company->id, + 'user_id' => $this->user->id, + 'balance' => 0, + ]); + + $ii = new InvoiceItem(); + $ii->cost = 100; + $ii->quantity = 1; + $ii->product_key = 'xx'; + $ii->notes = 'yy'; + + $i = \App\Models\Invoice::factory()->create([ + 'company_id' => $this->company->id, + 'user_id' => $this->user->id, + 'client_id' => $c->id, + 'tax_name1' => '', + 'tax_name2' => '', + 'tax_name3' => '', + 'tax_rate1' => 0, + 'tax_rate2' => 0, + 'tax_rate3' => 0, + 'discount' => 0, + 'line_items' => [ + $ii + ], + 'status_id' => 1, + ]); + + $i = $i->calc()->getInvoice(); + + $this->assertEquals(0, $i->balance); + $this->assertEquals(100, $i->amount); + + $i->service()->markSent()->save(); + + $this->assertEquals(100, $i->balance); + + $i->service()->markPaid()->save(); + $i = $i->fresh(); + $c = $c->fresh(); + + $this->assertEquals(0, $i->balance); + $this->assertEquals(0, $c->balance); + + $this->assertEquals(100, $c->paid_to_date); + + $i->service()->handleReversal()->save(); + + + $data = $i->toArray(); + $data['invoice_id'] = $i->hashed_id; + $data['user_id'] = $this->encodePrimaryKey($i->user_id); + $data['client_id'] = $this->encodePrimaryKey($i->client_id); + $data['status_id'] = 1; + + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->postJson("/api/v1/credits?mark_sent=true", $data); + + $response->assertStatus(200); + $arr = $response->json(); + + $cr_id = $arr['data']['id']; + + $i = $i->fresh(); + $c = $c->fresh(); + + $credit = $i->credits()->first(); + + $this->assertNotNull($credit); + + $this->assertEquals(0, $i->balance); + $this->assertEquals(100, $c->credit_balance); + $this->assertEquals(0, $c->paid_to_date); + + $credit->service()->deleteCredit()->save(); + + $c = $c->fresh(); + + $this->assertEquals(100, $c->paid_to_date); + $this->assertEquals(0, $c->credit_balance); + + $credit->service()->restoreCredit()->save(); + + $c = $c->fresh(); + + $this->assertEquals(0, $c->paid_to_date); + $this->assertEquals(100, $c->credit_balance); + + } + public function testCreditPaymentsPaidToDates() { $c = Client::factory()->create([ diff --git a/tests/Feature/MultiPaymentDeleteTest.php b/tests/Feature/MultiPaymentDeleteTest.php index 72c5e3640ac6..1b73e583495e 100644 --- a/tests/Feature/MultiPaymentDeleteTest.php +++ b/tests/Feature/MultiPaymentDeleteTest.php @@ -166,6 +166,7 @@ class MultiPaymentDeleteTest extends TestCase ], ], 'date' => '2019/12/12', + 'idempotency_key' => md5(time()), ]; $response = $this->withHeaders([ @@ -219,6 +220,7 @@ class MultiPaymentDeleteTest extends TestCase $this->assertEquals(162, $invoice->client->fresh()->balance); $this->assertEquals(163, $invoice->client->fresh()->paid_to_date); + sleep(1); // Pay 162 again and create payment #3 $data = [ @@ -232,6 +234,7 @@ class MultiPaymentDeleteTest extends TestCase ], ], 'date' => '2019/12/12', + 'idempotency_key' => md5(time()), ]; $response = $this->withHeaders([ diff --git a/tests/Feature/PaymentTest.php b/tests/Feature/PaymentTest.php index cf5816191f4d..696bf0b937e2 100644 --- a/tests/Feature/PaymentTest.php +++ b/tests/Feature/PaymentTest.php @@ -62,6 +62,38 @@ class PaymentTest extends TestCase ); } + public function testIdempotencyTrigger() + { + + $data = [ + 'amount' => 5, + 'client_id' => $this->client->hashed_id, + 'invoices' => [ + [ + 'invoice_id' => $this->invoice->hashed_id, + 'amount' => 5, + ], + ], + 'date' => '2020/12/11', + ]; + + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->postJson('/api/v1/payments/', $data); + + $response->assertStatus(200); + + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->postJson('/api/v1/payments/', $data); + + $response->assertStatus(422); + + } + + public function testInvoicesValidationProp() {