From 1e0f250052922384e35e96774b6e10a8538fc4de Mon Sep 17 00:00:00 2001 From: David Bomba Date: Sun, 16 Jun 2024 17:22:15 +1000 Subject: [PATCH 01/15] Fixes for paypal auth credentials --- .../ClientPortal/InvitationController.php | 1 + .../PayPal/PayPalBasePaymentDriver.php | 12 ++++++++++-- phpstan.neon | 2 +- 3 files changed, 12 insertions(+), 3 deletions(-) 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/PaymentDrivers/PayPal/PayPalBasePaymentDriver.php b/app/PaymentDrivers/PayPal/PayPalBasePaymentDriver.php index 26ad7f06568f..5120932fd9b1 100644 --- a/app/PaymentDrivers/PayPal/PayPalBasePaymentDriver.php +++ b/app/PaymentDrivers/PayPal/PayPalBasePaymentDriver.php @@ -114,8 +114,16 @@ class PayPalBasePaymentDriver extends BaseDriver $this->api_endpoint_url = $this->company_gateway->getConfigField('testMode') ? 'https://api-m.sandbox.paypal.com' : 'https://api-m.paypal.com'; - $secret = $this->company_gateway->getConfigField('secret'); - $client_id = $this->company_gateway->getConfigField('clientId'); + if(\App\Utils\Ninja::isHosted()) { + $secret = config('ninja.paypal.secret'); + $client_id = config('ninja.paypal.client_id'); + + } + else { + + $secret = $this->company_gateway->getConfigField('secret'); + $client_id = $this->company_gateway->getConfigField('clientId'); + } if($this->access_token && $this->token_expiry && $this->token_expiry->isFuture()) { return $this; diff --git a/phpstan.neon b/phpstan.neon index 5c586c4bb520..718f0385499c 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -3,7 +3,7 @@ includes: - ./vendor/spaze/phpstan-stripe/extension.neon - phpstan-baseline.neon parameters: - level: 3 + level: 4 paths: - app excludePaths: From 38114d0c482c660f3e649bb0234aa630502b07b7 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Sun, 16 Jun 2024 19:16:42 +1000 Subject: [PATCH 02/15] Minor fixes - add referral code to user transformer --- app/PaymentDrivers/CheckoutCom/CheckoutWebhook.php | 2 +- app/Transformers/UserTransformer.php | 3 ++- .../portal/ninja2020/gateways/paypal/ppcp/card.blade.php | 5 ++++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/app/PaymentDrivers/CheckoutCom/CheckoutWebhook.php b/app/PaymentDrivers/CheckoutCom/CheckoutWebhook.php index 26701b1f0311..1004319ee6fa 100644 --- a/app/PaymentDrivers/CheckoutCom/CheckoutWebhook.php +++ b/app/PaymentDrivers/CheckoutCom/CheckoutWebhook.php @@ -46,7 +46,7 @@ class CheckoutWebhook implements ShouldQueue public function handle() { - nlog("Checkout Webhook"); + // nlog("Checkout Webhook"); MultiDB::findAndSetDbByCompanyKey($this->company_key); diff --git a/app/Transformers/UserTransformer.php b/app/Transformers/UserTransformer.php index 3f4ec9801ac8..83d4d8fb10a0 100644 --- a/app/Transformers/UserTransformer.php +++ b/app/Transformers/UserTransformer.php @@ -63,8 +63,9 @@ class UserTransformer extends EntityTransformer 'has_password' => (bool) empty($user->password) ? false : true, 'oauth_user_token' => empty($user->oauth_user_token) ? '' : '***', 'verified_phone_number' => (bool) $user->verified_phone_number, - 'language_id' => (string) $user->language_id ?? '', + 'language_id' => (string) $user->language_id ?: '', 'user_logged_in_notification' => (bool) $user->user_logged_in_notification, + 'referral_code' => (string) $user->referral_code, ]; } diff --git a/resources/views/portal/ninja2020/gateways/paypal/ppcp/card.blade.php b/resources/views/portal/ninja2020/gateways/paypal/ppcp/card.blade.php index b90ae91f753a..38db67ac5138 100644 --- a/resources/views/portal/ninja2020/gateways/paypal/ppcp/card.blade.php +++ b/resources/views/portal/ninja2020/gateways/paypal/ppcp/card.blade.php @@ -14,7 +14,10 @@ @endphp @section('gateway_head') - + @endsection @section('gateway_content') From 742b49c75aecb3b3a5edac4847203a848f358226 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Mon, 17 Jun 2024 10:14:04 +1000 Subject: [PATCH 03/15] Fixes for subscription cron query --- app/Export/CSV/QuoteExport.php | 10 +- app/Export/CSV/TaskExport.php | 12 +- app/Export/CSV/VendorExport.php | 20 +- .../RecurringExpenseToExpenseFactory.php | 4 +- app/Filters/InvoiceFilters.php | 3 +- app/Filters/PaymentFilters.php | 1 - app/Filters/RecurringInvoiceFilters.php | 4 +- app/Filters/TaskFilters.php | 1 + app/Helpers/Epc/EpcQrGenerator.php | 24 +- .../Invoice/InvoiceItemSumInclusive.php | 2 +- app/Helpers/Invoice/ProRata.php | 4 +- .../Auth/ContactForgotPasswordController.php | 8 +- .../Auth/ContactLoginController.php | 2 +- .../Auth/ResetPasswordController.php | 4 +- app/Http/Controllers/BaseController.php | 2 +- app/Http/Controllers/BrevoController.php | 1 - app/Http/Controllers/ClientController.php | 4 +- .../ClientPortal/InvoiceController.php | 4 +- .../ClientPortal/PaymentController.php | 1 + app/Http/Middleware/PasswordProtection.php | 2 +- app/Jobs/Cron/SubscriptionCron.php | 11 +- app/Jobs/Ninja/TaskScheduler.php | 2 +- app/Models/Invoice.php | 1 - app/Models/Payment.php | 2 +- app/Services/Scheduler/EmailReport.php | 5 +- app/Services/Template/TemplateService.php | 7 +- app/Utils/Helpers.php | 10 +- app/Utils/HtmlEngine.php | 241 +++++++++--------- app/Utils/PaymentHtmlEngine.php | 18 +- app/Utils/TemplateEngine.php | 6 +- 30 files changed, 202 insertions(+), 214 deletions(-) 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..de59952d871c 100644 --- a/app/Factory/RecurringExpenseToExpenseFactory.php +++ b/app/Factory/RecurringExpenseToExpenseFactory.php @@ -144,7 +144,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 +182,7 @@ class RecurringExpenseToExpenseFactory $value, 1 ); - } + // } } // Second case with more common calculations. 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/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/InvoiceItemSumInclusive.php b/app/Helpers/Invoice/InvoiceItemSumInclusive.php index 3ecbf7431d36..88416f6c8696 100644 --- a/app/Helpers/Invoice/InvoiceItemSumInclusive.php +++ b/app/Helpers/Invoice/InvoiceItemSumInclusive.php @@ -399,7 +399,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()) { $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/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/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/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/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/Models/Invoice.php b/app/Models/Invoice.php index 70dfd979a814..07ef8532baee 100644 --- a/app/Models/Invoice.php +++ b/app/Models/Invoice.php @@ -130,7 +130,6 @@ use Laracasts\Presenter\PresentableTrait; * @property-read \Illuminate\Database\Eloquent\Collection $invitations * @property-read \Illuminate\Database\Eloquent\Collection $payments * @property-read \Illuminate\Database\Eloquent\Collection $tasks - * @method static \Illuminate\Database\Eloquent\Builder|BaseModel company() * @property object|null $tax_data * @mixin \Eloquent */ diff --git a/app/Models/Payment.php b/app/Models/Payment.php index 39dc117fd609..42155828e831 100644 --- a/app/Models/Payment.php +++ b/app/Models/Payment.php @@ -58,7 +58,7 @@ use Illuminate\Database\Eloquent\SoftDeletes; * @property int|null $exchange_currency_id * @property \App\Models\Paymentable $paymentable * @property object|null $meta - * @property object|null $refund_meta + * @property array|null $refund_meta * @property string|null $custom_value1 * @property string|null $custom_value2 * @property string|null $custom_value3 diff --git a/app/Services/Scheduler/EmailReport.php b/app/Services/Scheduler/EmailReport.php index 9a4487109c6b..2dd93ee32e8f 100644 --- a/app/Services/Scheduler/EmailReport.php +++ b/app/Services/Scheduler/EmailReport.php @@ -46,9 +46,9 @@ class EmailReport use MakesHash; use MakesDates; - private Client $client; + // private Client $client; - private bool $multiple_clients = false; + // private bool $multiple_clients = false; private string $file_name = 'file.csv'; @@ -66,6 +66,7 @@ class EmailReport $data['end_date'] = $start_end_dates[1]; $data['date_range'] = $data['date_range'] ?? 'all'; $data['report_keys'] = $data['report_keys'] ?? []; + $data['include_deleted'] = $data['include_deleted'] ?? false; $export = false; diff --git a/app/Services/Template/TemplateService.php b/app/Services/Template/TemplateService.php index 14babd5de3aa..7df008689d3a 100644 --- a/app/Services/Template/TemplateService.php +++ b/app/Services/Template/TemplateService.php @@ -124,7 +124,7 @@ class TemplateService $this->twig->addFilter($filter); $allowedTags = ['if', 'for', 'set', 'filter']; - $allowedFilters = ['escape', 'e', 'upper', 'lower', 'capitalize', 'filter', 'length', 'merge','format_currency','map', 'join', 'first', 'date','sum']; + $allowedFilters = ['escape', 'e', 'upper', 'lower', 'capitalize', 'filter', 'length', 'merge','format_currency', 'format_number','format_percent_number','map', 'join', 'first', 'date','sum']; $allowedFunctions = ['range', 'cycle', 'constant', 'date',]; $allowedProperties = ['type_id']; $allowedMethods = ['img','t']; @@ -620,8 +620,6 @@ class TemplateService private function transformPayment(Payment $payment): array { - $data = []; - $this->payment = $payment; $credits = $payment->credits->map(function ($credit) use ($payment) { @@ -694,8 +692,6 @@ class TemplateService 'refund_activity' => $this->getPaymentRefundActivity($payment), ]; - return $data; - } /** @@ -1196,6 +1192,7 @@ class TemplateService 'company-details' => $this->companyDetails($stack['labels'] == 'true'), 'company-address' => $this->companyAddress($stack['labels'] == 'true'), 'shipping-details' => $this->shippingDetails($stack['labels'] == 'true'), + default => $this->entityDetails(), }; $this->save(); diff --git a/app/Utils/Helpers.php b/app/Utils/Helpers.php index 21db9ad6f90f..4d5fd38d486d 100644 --- a/app/Utils/Helpers.php +++ b/app/Utils/Helpers.php @@ -97,15 +97,15 @@ class Helpers switch ($custom_field) { case 'date': return is_null($entity) ? $value : $this->translateDate($value, $entity->date_format(), $entity->locale()); - break; + case 'switch': return trim($value ?? '') == 'yes' ? ctrans('texts.yes') : ctrans('texts.no'); - break; + default: return is_null($value) ? '' : $this->processReservedKeywords($value, $entity); - break; + } } @@ -252,7 +252,7 @@ class Helpers continue; } - if (Str::contains($match, '|')) { + // if (Str::contains($match, '|')) { $parts = explode('|', $match); // [ '[MONTH', 'MONTH+2]' ] $left = substr($parts[0], 1); // 'MONTH' @@ -290,7 +290,7 @@ class Helpers $value, 1 ); - } + // } } // Second case with more common calculations. diff --git a/app/Utils/HtmlEngine.php b/app/Utils/HtmlEngine.php index 3f34611e0d24..5efa54297ccf 100644 --- a/app/Utils/HtmlEngine.php +++ b/app/Utils/HtmlEngine.php @@ -45,7 +45,7 @@ class HtmlEngine /** @var \App\Models\Client $client */ public $client; - /** @var \App\Models\ClientContact $contact */ + /** @var ?\App\Models\ClientContact $contact */ public $contact; /** @var \App\Models\Company $company */ @@ -120,7 +120,7 @@ class HtmlEngine { if (! $this->client->currency()) { throw new Exception(debug_backtrace()[1]['function'], 1); - exit; + // exit; } App::forgetInstance('translator'); @@ -132,10 +132,10 @@ class HtmlEngine $data['$global_margin'] = ['value' => '6.35mm', 'label' => '']; $data['$company_logo_size'] = ['value' => $this->resolveCompanyLogoSize(), 'label' => '']; - $data['$show_shipping_address'] = ['value' => $this->settings?->show_shipping_address ? 'flex' : 'none', 'label' => '']; - $data['$show_shipping_address_block'] = ['value' => $this->settings?->show_shipping_address ? 'block' : 'none', 'label' => '']; + $data['$show_shipping_address'] = ['value' => $this->settings->show_shipping_address ? 'flex' : 'none', 'label' => '']; + $data['$show_shipping_address_block'] = ['value' => $this->settings->show_shipping_address ? 'block' : 'none', 'label' => '']; // $data['$show_shipping_address_visibility'] = ['value' => $this->settings?->show_shipping_address ? 'visible' : 'hidden', 'label' => '']; - $data['$show_shipping_address_visibility'] = ['value' => $this->settings?->show_shipping_address ? 1 : 0, 'label' => '']; + $data['$show_shipping_address_visibility'] = ['value' => $this->settings->show_shipping_address ? 1 : 0, 'label' => '']; $data['$order_number'] = ['value' => '', 'label' => ctrans('texts.order_number')]; $data['$tax'] = ['value' => '', 'label' => ctrans('texts.tax')]; @@ -226,7 +226,7 @@ class HtmlEngine $data['$status_logo'] = ['value' => '
' . ctrans('texts.paid') .'
', 'label' => '']; - $data['$show_paid_stamp'] = ['value' => $this->entity->status_id == 4 && $this->settings?->show_paid_stamp ? 'flex' : 'none', 'label' => '']; + $data['$show_paid_stamp'] = ['value' => $this->entity->status_id == 4 && $this->settings->show_paid_stamp ? 'flex' : 'none', 'label' => '']; if ($this->entity->vendor) { $data['$invoice.vendor'] = ['value' => $this->entity->vendor->present()->name(), 'label' => ctrans('texts.vendor_name')]; @@ -775,8 +775,7 @@ class HtmlEngine return ''; } - return - collect($payment->refund_meta) + return collect($payment->refund_meta) ->map(function ($refund) use ($payment) { $date = \Carbon\Carbon::parse($refund['date'] ?? $payment->date)->addSeconds($payment->client->timezone_offset()); @@ -962,20 +961,20 @@ class HtmlEngine * @return string a collection of rows with line item * aggregate data */ - private function makeLineTaxes(): string - { - $tax_map = $this->entity_calc->getTaxMap(); + // private function makeLineTaxes(): string + // { + // $tax_map = $this->entity_calc->getTaxMap(); - $data = ''; + // $data = ''; - foreach ($tax_map as $tax) { - $data .= ''; - $data .= ''.$tax['name'].''; - $data .= ''.Number::formatMoney($tax['total'], $this->client).''; - } + // foreach ($tax_map as $tax) { + // $data .= ''; + // $data .= ''.$tax['name'].''; + // $data .= ''.Number::formatMoney($tax['total'], $this->client).''; + // } - return $data; - } + // return $data; + // } private function lineTaxValues(): string { @@ -990,30 +989,30 @@ class HtmlEngine return $data; } - private function makeTotalTaxes(): string - { - $data = ''; + // private function makeTotalTaxes(): string + // { + // $data = ''; - if (! $this->entity_calc->getTotalTaxMap()) { - return $data; - } + // if (! $this->entity_calc->getTotalTaxMap()) { + // return $data; + // } - foreach ($this->entity_calc->getTotalTaxMap() as $tax) { - $data .= ''; - $data .= ''; - $data .= ''.$tax['name'].''; - $data .= ''.Number::formatMoney($tax['total'], $this->client).''; - } + // foreach ($this->entity_calc->getTotalTaxMap() as $tax) { + // $data .= ''; + // $data .= ''; + // $data .= ''.$tax['name'].''; + // $data .= ''.Number::formatMoney($tax['total'], $this->client).''; + // } - return $data; - } + // return $data; + // } - private function parseLabelsAndValues($labels, $values, $section): string - { - $section = strtr($section, $labels); + // private function parseLabelsAndValues($labels, $values, $section): string + // { + // $section = strtr($section, $labels); - return strtr($section, $values); - } + // return strtr($section, $values); + // } /* | Ensures the URL doesn't have duplicated trailing slash @@ -1029,98 +1028,98 @@ class HtmlEngine * of Repeating headers and footers on the PDF. * @return string The css string */ - private function generateCustomCSS(): string - { - $header_and_footer = ' -.header, .header-space { - height: 160px; -} +// private function generateCustomCSS(): string +// { +// $header_and_footer = ' +// .header, .header-space { +// height: 160px; +// } -.footer, .footer-space { - height: 160px; -} +// .footer, .footer-space { +// height: 160px; +// } -.footer { - position: fixed; - bottom: 0; - width: 100%; -} +// .footer { +// position: fixed; +// bottom: 0; +// width: 100%; +// } -.header { - position: fixed; - top: 0mm; - width: 100%; -} +// .header { +// position: fixed; +// top: 0mm; +// width: 100%; +// } -@media print { - thead {display: table-header-group;} - tfoot {display: table-footer-group;} - button {display: none;} - body {margin: 0;} -}'; +// @media print { +// thead {display: table-header-group;} +// tfoot {display: table-footer-group;} +// button {display: none;} +// body {margin: 0;} +// }'; - $header = ' -.header, .header-space { - height: 160px; -} +// $header = ' +// .header, .header-space { +// height: 160px; +// } -.header { - position: fixed; - top: 0mm; - width: 100%; -} +// .header { +// position: fixed; +// top: 0mm; +// width: 100%; +// } -@media print { - thead {display: table-header-group;} - button {display: none;} - body {margin: 0;} -}'; +// @media print { +// thead {display: table-header-group;} +// button {display: none;} +// body {margin: 0;} +// }'; - $footer = ' +// $footer = ' -.footer, .footer-space { - height: 160px; -} +// .footer, .footer-space { +// height: 160px; +// } -.footer { - position: fixed; - bottom: 0; - width: 100%; -} +// .footer { +// position: fixed; +// bottom: 0; +// width: 100%; +// } -@media print { - tfoot {display: table-footer-group;} - button {display: none;} - body {margin: 0;} -}'; - $css = ''; +// @media print { +// tfoot {display: table-footer-group;} +// button {display: none;} +// body {margin: 0;} +// }'; +// $css = ''; - if ($this->settings->all_pages_header && $this->settings->all_pages_footer) { - $css .= $header_and_footer; - } elseif ($this->settings->all_pages_header && ! $this->settings->all_pages_footer) { - $css .= $header; - } elseif (! $this->settings->all_pages_header && $this->settings->all_pages_footer) { - $css .= $footer; - } +// if ($this->settings->all_pages_header && $this->settings->all_pages_footer) { +// $css .= $header_and_footer; +// } elseif ($this->settings->all_pages_header && ! $this->settings->all_pages_footer) { +// $css .= $header; +// } elseif (! $this->settings->all_pages_header && $this->settings->all_pages_footer) { +// $css .= $footer; +// } - $css .= ' -.page { - page-break-after: always; -} +// $css .= ' +// .page { +// page-break-after: always; +// } -@page { - margin: 0mm -} +// @page { +// margin: 0mm +// } -html { - '; +// html { +// '; - $css .= 'font-size:'.$this->settings->font_size.'px;'; +// $css .= 'font-size:'.$this->settings->font_size.'px;'; - $css .= '}'; +// $css .= '}'; - return $css; - } +// return $css; +// } /** * Generate markup for HTML images on entity. @@ -1200,14 +1199,14 @@ html { '; - return ' - - - - -
- '. $text .' -
- '; + // return ' + // + // + // + // + //
+ // '. $text .' + //
+ // '; } } diff --git a/app/Utils/PaymentHtmlEngine.php b/app/Utils/PaymentHtmlEngine.php index 8562d22bea67..b28641606c86 100644 --- a/app/Utils/PaymentHtmlEngine.php +++ b/app/Utils/PaymentHtmlEngine.php @@ -355,14 +355,14 @@ class PaymentHtmlEngine '; - return ' - - - - -
- '. $text .' -
- '; + // return ' + // + // + // + // + //
+ // '. $text .' + //
+ // '; } } diff --git a/app/Utils/TemplateEngine.php b/app/Utils/TemplateEngine.php index ba3ad307e8af..3b697e203c25 100644 --- a/app/Utils/TemplateEngine.php +++ b/app/Utils/TemplateEngine.php @@ -240,8 +240,10 @@ class TemplateEngine } else { $data['signature'] = $this->settings->email_signature; $data['settings'] = $this->settings; - $data['whitelabel'] = $this->entity_obj ? $this->entity_obj->company->account->isPaid() : true; - $data['company'] = $this->entity_obj ? $this->entity_obj->company : ''; + // $data['whitelabel'] = $this->entity_obj ? $this->entity_obj->company->account->isPaid() : true; + // $data['company'] = $this->entity_obj ? $this->entity_obj->company : ''; + $data['whitelabel'] = $this->entity_obj->company->account->isPaid(); + $data['company'] = $this->entity_obj->company; $data['settings'] = $this->settings; } From 11e082d4435459fc858d1698781d2c9e49b50bc4 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Mon, 17 Jun 2024 13:45:24 +1000 Subject: [PATCH 04/15] Fixes for credits --- app/Helpers/Invoice/InvoiceItemSum.php | 3 +- .../Invoice/InvoiceItemSumInclusive.php | 5 +- app/Http/Controllers/MigrationController.php | 338 +++++++++--------- .../Controllers/OneTimeTokenController.php | 2 - app/Http/Controllers/PostMarkController.php | 1 - app/Http/Controllers/SetupController.php | 18 - .../Invoice2Go/InvoiceTransformer.php | 2 +- app/Jobs/Entity/CreateRawPdf.php | 10 +- app/Jobs/Invoice/CreateUbl.php | 2 +- app/Models/User.php | 2 +- app/PaymentDrivers/Braintree/CreditCard.php | 2 +- app/PaymentDrivers/PayPal/PayPalWebhook.php | 2 +- .../PayPalPPCPPaymentDriver.php | 4 + app/Repositories/PaymentRepository.php | 2 +- app/Services/Credit/CreditService.php | 36 +- .../EDocument/Standards/RoEInvoice.php | 2 +- app/Services/Email/EmailDefaults.php | 2 +- app/Utils/Traits/CleanLineItems.php | 2 - tests/Feature/CreditTest.php | 96 +++++ 19 files changed, 295 insertions(+), 236 deletions(-) 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 88416f6c8696..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/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/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/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/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/Models/User.php b/app/Models/User.php index 102c4625c502..e3c03c63ebf5 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -60,7 +60,7 @@ use Laracasts\Presenter\PresentableTrait; * @property bool $is_deleted * @property string|null $last_login * @property string|null $signature - * @property string $password + * @property string|null $password * @property string $language_id * @property string|null $remember_token * @property string|null $custom_value1 diff --git a/app/PaymentDrivers/Braintree/CreditCard.php b/app/PaymentDrivers/Braintree/CreditCard.php index 654890cf0690..8ba6e0154f58 100644 --- a/app/PaymentDrivers/Braintree/CreditCard.php +++ b/app/PaymentDrivers/Braintree/CreditCard.php @@ -53,7 +53,7 @@ class CreditCard * Credit card payment page. * * @param array $data - * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View + * @return array */ private function threeDParameters(array $data) diff --git a/app/PaymentDrivers/PayPal/PayPalWebhook.php b/app/PaymentDrivers/PayPal/PayPalWebhook.php index e4ba19d442fd..2840e5ccb4ce 100644 --- a/app/PaymentDrivers/PayPal/PayPalWebhook.php +++ b/app/PaymentDrivers/PayPal/PayPalWebhook.php @@ -307,7 +307,7 @@ class PayPalWebhook implements ShouldQueue }); - return $gateway ?? false; + return $gateway ?? null; } //--------------------------------------------------------------------------------------// diff --git a/app/PaymentDrivers/PayPalPPCPPaymentDriver.php b/app/PaymentDrivers/PayPalPPCPPaymentDriver.php index 1803265d4b7e..14fd0ace2dcb 100644 --- a/app/PaymentDrivers/PayPalPPCPPaymentDriver.php +++ b/app/PaymentDrivers/PayPalPPCPPaymentDriver.php @@ -284,6 +284,10 @@ class PayPalPPCPPaymentDriver extends PayPalBasePaymentDriver $r = $this->gatewayRequest('/v2/checkout/orders', 'post', $order); + if(!isset($r->json()['id'])) { + $this->handleProcessingFailure($r->json()); + } + $this->payment_hash->withData("orderID", $r->json()['id']); return $r->json()['id']; diff --git a/app/Repositories/PaymentRepository.php b/app/Repositories/PaymentRepository.php index f0924ec7b59d..e7879ec8dd11 100644 --- a/app/Repositories/PaymentRepository.php +++ b/app/Repositories/PaymentRepository.php @@ -59,7 +59,7 @@ class PaymentRepository extends BaseRepository * @param Payment $payment The $payment entity * @return Payment The updated/created payment object */ - private function applyPayment(array $data, Payment $payment): ?Payment + private function applyPayment(array $data, Payment $payment): Payment { $is_existing_payment = true; $client = false; diff --git a/app/Services/Credit/CreditService.php b/app/Services/Credit/CreditService.php index 9474058f85f9..927bc3c16a75 100644 --- a/app/Services/Credit/CreditService.php +++ b/app/Services/Credit/CreditService.php @@ -219,27 +219,6 @@ class CreditService public function deletePdf() { - $this->credit->invitations->each(function ($invitation) { - // (new UnlinkFile(config('filesystems.default'), $this->credit->client->credit_filepath($invitation).$this->credit->numberFormatter().'.pdf'))->handle(); - - //30-06-2023 - try { - // if (Storage::disk(config('filesystems.default'))->exists($this->invoice->client->invoice_filepath($invitation).$this->invoice->numberFormatter().'.pdf')) { - Storage::disk(config('filesystems.default'))->delete($this->credit->client->credit_filepath($invitation).$this->credit->numberFormatter().'.pdf'); - // } - - // if (Ninja::isHosted() && Storage::disk('public')->exists($this->invoice->client->invoice_filepath($invitation).$this->invoice->numberFormatter().'.pdf')) { - if (Ninja::isHosted()) { - Storage::disk('public')->delete($this->credit->client->credit_filepath($invitation).$this->credit->numberFormatter().'.pdf'); - } - } catch (\Exception $e) { - nlog($e->getMessage()); - } - - - - }); - return $this; } @@ -273,11 +252,14 @@ class CreditService public function deleteCredit() { + $paid_to_date = $this->credit->invoice_id ? $this->credit->balance : 0; + $this->credit - ->client - ->service() - ->adjustCreditBalance($this->credit->balance * -1) - ->save(); + ->client + ->service() + ->updatePaidToDate($paid_to_date) + ->adjustCreditBalance($this->credit->balance * -1) + ->save(); return $this; } @@ -285,9 +267,13 @@ class CreditService public function restoreCredit() { + + $paid_to_date = $this->credit->invoice_id ? $this->credit->balance : 0; + $this->credit ->client ->service() + ->updatePaidToDate($paid_to_date * -1) ->adjustCreditBalance($this->credit->balance) ->save(); diff --git a/app/Services/EDocument/Standards/RoEInvoice.php b/app/Services/EDocument/Standards/RoEInvoice.php index ebee4d1fcd38..016f810d4e9c 100644 --- a/app/Services/EDocument/Standards/RoEInvoice.php +++ b/app/Services/EDocument/Standards/RoEInvoice.php @@ -405,7 +405,7 @@ class RoEInvoice extends AbstractService /** * @param $item * @param $invoice_total - * @return float|int + * @return float */ private function getItemTaxable($item, $invoice_total) { diff --git a/app/Services/Email/EmailDefaults.php b/app/Services/Email/EmailDefaults.php index 068ad85c77ad..25a7d0204b32 100644 --- a/app/Services/Email/EmailDefaults.php +++ b/app/Services/Email/EmailDefaults.php @@ -406,7 +406,7 @@ class EmailDefaults * @param string $markdown The body to convert * @return string The parsed markdown response */ - private function parseMarkdownToHtml(string $markdown): ?string + private function parseMarkdownToHtml(string $markdown): string { $converter = new CommonMarkConverter([ 'allow_unsafe_links' => false, diff --git a/app/Utils/Traits/CleanLineItems.php b/app/Utils/Traits/CleanLineItems.php index 9cd45a73f576..e82623bd3f0a 100644 --- a/app/Utils/Traits/CleanLineItems.php +++ b/app/Utils/Traits/CleanLineItems.php @@ -110,8 +110,6 @@ trait CleanLineItems $total += ($item['cost'] * $item['quantity']); } - nlog($total); - return $total; } } 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([ From 13405c1805ce1e2a870004c00cdcc1696a756664 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Mon, 17 Jun 2024 16:08:06 +1000 Subject: [PATCH 05/15] Static Analysis + ACSS --- app/Http/Controllers/CompanyController.php | 2 +- .../Controllers/CompanyUserController.php | 3 - app/Http/Controllers/CreditController.php | 5 +- app/Http/Controllers/EmailController.php | 18 +-- .../PreviewPurchaseOrderController.php | 133 ------------------ .../ProtectedDownloadController.php | 1 - app/Http/Controllers/QuoteController.php | 1 - app/Import/Transformer/BaseTransformer.php | 1 - app/Jobs/Company/CompanyImport.php | 19 +-- app/Jobs/Util/Import.php | 7 - app/Jobs/Vendor/CreatePurchaseOrderPdf.php | 12 -- app/Libraries/OAuth/OAuth.php | 1 - app/Mail/Engine/PaymentEmailEngine.php | 9 -- app/PaymentDrivers/BraintreePaymentDriver.php | 1 - .../PayPal/PayPalBasePaymentDriver.php | 4 +- app/Services/Tax/Providers/TaxProvider.php | 2 +- app/Transformers/ProjectTransformer.php | 2 +- .../gateways/stripe/acss/authorize.blade.php | 2 +- 18 files changed, 19 insertions(+), 204 deletions(-) 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/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/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/Import/Transformer/BaseTransformer.php b/app/Import/Transformer/BaseTransformer.php index 32a333f66e98..dbaa16d75c22 100644 --- a/app/Import/Transformer/BaseTransformer.php +++ b/app/Import/Transformer/BaseTransformer.php @@ -658,7 +658,6 @@ class BaseTransformer public function getExpenseCategoryId($name) { /** @var \App\Models\ExpenseCategory $ec */ - $ec = ExpenseCategory::query()->where('company_id', $this->company->id) ->where('is_deleted', false) ->whereRaw("LOWER(REPLACE(`name`, ' ' ,'')) = ?", [ 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/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/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 .' -
- '; } } diff --git a/app/PaymentDrivers/BraintreePaymentDriver.php b/app/PaymentDrivers/BraintreePaymentDriver.php index 9fe58cf6b9e1..74a7e7813e64 100644 --- a/app/PaymentDrivers/BraintreePaymentDriver.php +++ b/app/PaymentDrivers/BraintreePaymentDriver.php @@ -354,7 +354,6 @@ class BraintreePaymentDriver extends BaseDriver return false; } - return false; } private function findTokens(string $gateway_customer_reference) diff --git a/app/PaymentDrivers/PayPal/PayPalBasePaymentDriver.php b/app/PaymentDrivers/PayPal/PayPalBasePaymentDriver.php index 5120932fd9b1..0db7ff2ac382 100644 --- a/app/PaymentDrivers/PayPal/PayPalBasePaymentDriver.php +++ b/app/PaymentDrivers/PayPal/PayPalBasePaymentDriver.php @@ -450,11 +450,11 @@ class PayPalBasePaymentDriver extends BaseDriver switch ($response['name']) { case 'NOT_AUTHORIZED': throw new PaymentFailed("There was a permissions issue processing this payment, please contact the merchant. ", 401); - break; + default: throw new PaymentFailed("Unknown error occurred processing payment. Please contact merchant.", 500); - break; + } } diff --git a/app/Services/Tax/Providers/TaxProvider.php b/app/Services/Tax/Providers/TaxProvider.php index 1e65d0f170a3..44585c75bb25 100644 --- a/app/Services/Tax/Providers/TaxProvider.php +++ b/app/Services/Tax/Providers/TaxProvider.php @@ -225,7 +225,7 @@ class TaxProvider { throw new \Exception("No tax region defined for this country"); - $this->provider = EuTax::class; + // $this->provider = EuTax::class; return $this; } diff --git a/app/Transformers/ProjectTransformer.php b/app/Transformers/ProjectTransformer.php index cdf5184219c6..0d0bfa253f10 100644 --- a/app/Transformers/ProjectTransformer.php +++ b/app/Transformers/ProjectTransformer.php @@ -47,7 +47,7 @@ class ProjectTransformer extends EntityTransformer { $transformer = new DocumentTransformer($this->serializer); - if($project->documents) { + if($project->documents->count() > 0) { return $this->includeCollection($project->documents, $transformer, Document::class); } diff --git a/resources/views/portal/ninja2020/gateways/stripe/acss/authorize.blade.php b/resources/views/portal/ninja2020/gateways/stripe/acss/authorize.blade.php index ee9b21d32f0b..5199d8d8427f 100644 --- a/resources/views/portal/ninja2020/gateways/stripe/acss/authorize.blade.php +++ b/resources/views/portal/ninja2020/gateways/stripe/acss/authorize.blade.php @@ -34,7 +34,7 @@

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.

From 97049f36a9a09b7ea3f8554318c78df083409251 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Mon, 17 Jun 2024 16:34:26 +1000 Subject: [PATCH 06/15] Fixes for includes --- app/Transformers/ProjectTransformer.php | 6 +- composer.lock | 89 +++++++++++++------------ 2 files changed, 49 insertions(+), 46 deletions(-) diff --git a/app/Transformers/ProjectTransformer.php b/app/Transformers/ProjectTransformer.php index 0d0bfa253f10..c9eb2dbc20a4 100644 --- a/app/Transformers/ProjectTransformer.php +++ b/app/Transformers/ProjectTransformer.php @@ -47,11 +47,11 @@ class ProjectTransformer extends EntityTransformer { $transformer = new DocumentTransformer($this->serializer); - if($project->documents->count() > 0) { + // if($project->documents->count() > 0) { return $this->includeCollection($project->documents, $transformer, Document::class); - } + // } - return null; + // return null; } public function includeClient(Project $project): ?\League\Fractal\Resource\Item diff --git a/composer.lock b/composer.lock index 0d5f7c627536..21c4bbab2596 100644 --- a/composer.lock +++ b/composer.lock @@ -1385,16 +1385,16 @@ }, { "name": "aws/aws-sdk-php", - "version": "3.314.1", + "version": "3.314.2", "source": { "type": "git", "url": "https://github.com/aws/aws-sdk-php.git", - "reference": "85207a1f342443f40711ac8fe246120821370f11" + "reference": "1f5ccf9c73a66fb85c7c5de8f11ed69e44c636ef" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/85207a1f342443f40711ac8fe246120821370f11", - "reference": "85207a1f342443f40711ac8fe246120821370f11", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/1f5ccf9c73a66fb85c7c5de8f11ed69e44c636ef", + "reference": "1f5ccf9c73a66fb85c7c5de8f11ed69e44c636ef", "shasum": "" }, "require": { @@ -1474,9 +1474,9 @@ "support": { "forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80", "issues": "https://github.com/aws/aws-sdk-php/issues", - "source": "https://github.com/aws/aws-sdk-php/tree/3.314.1" + "source": "https://github.com/aws/aws-sdk-php/tree/3.314.2" }, - "time": "2024-06-13T18:07:00+00:00" + "time": "2024-06-14T18:11:34+00:00" }, { "name": "bacon/bacon-qr-code", @@ -3602,16 +3602,16 @@ }, { "name": "google/apiclient-services", - "version": "v0.359.0", + "version": "v0.360.0", "source": { "type": "git", "url": "https://github.com/googleapis/google-api-php-client-services.git", - "reference": "e975e6d0efa47f7e49280c4ea7fd6a93b6d7e338" + "reference": "e48813050e660c7dcbe48cb6556461efe6381a54" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/googleapis/google-api-php-client-services/zipball/e975e6d0efa47f7e49280c4ea7fd6a93b6d7e338", - "reference": "e975e6d0efa47f7e49280c4ea7fd6a93b6d7e338", + "url": "https://api.github.com/repos/googleapis/google-api-php-client-services/zipball/e48813050e660c7dcbe48cb6556461efe6381a54", + "reference": "e48813050e660c7dcbe48cb6556461efe6381a54", "shasum": "" }, "require": { @@ -3640,9 +3640,9 @@ ], "support": { "issues": "https://github.com/googleapis/google-api-php-client-services/issues", - "source": "https://github.com/googleapis/google-api-php-client-services/tree/v0.359.0" + "source": "https://github.com/googleapis/google-api-php-client-services/tree/v0.360.0" }, - "time": "2024-06-10T01:02:17+00:00" + "time": "2024-06-17T01:06:20+00:00" }, { "name": "google/auth", @@ -4630,16 +4630,16 @@ }, { "name": "horstoeko/zugferd", - "version": "v1.0.54", + "version": "v1.0.56", "source": { "type": "git", "url": "https://github.com/horstoeko/zugferd.git", - "reference": "91547c8aee9d8da22568b90d7cedfaba15373ebe" + "reference": "ae34e6450d125850c5c001100b459d46e9b37150" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/horstoeko/zugferd/zipball/91547c8aee9d8da22568b90d7cedfaba15373ebe", - "reference": "91547c8aee9d8da22568b90d7cedfaba15373ebe", + "url": "https://api.github.com/repos/horstoeko/zugferd/zipball/ae34e6450d125850c5c001100b459d46e9b37150", + "reference": "ae34e6450d125850c5c001100b459d46e9b37150", "shasum": "" }, "require": { @@ -4699,9 +4699,9 @@ ], "support": { "issues": "https://github.com/horstoeko/zugferd/issues", - "source": "https://github.com/horstoeko/zugferd/tree/v1.0.54" + "source": "https://github.com/horstoeko/zugferd/tree/v1.0.56" }, - "time": "2024-06-07T07:47:18+00:00" + "time": "2024-06-15T05:49:47+00:00" }, { "name": "http-interop/http-factory-guzzle", @@ -5472,16 +5472,16 @@ }, { "name": "josemmo/facturae-php", - "version": "v1.8.0", + "version": "v1.8.1", "source": { "type": "git", "url": "https://github.com/josemmo/Facturae-PHP.git", - "reference": "102edbb00b883d41da7306abf78a1695f7df406c" + "reference": "c7f01f5d00a82bcaa1bdb9cfe7029cc7d8296fc4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/josemmo/Facturae-PHP/zipball/102edbb00b883d41da7306abf78a1695f7df406c", - "reference": "102edbb00b883d41da7306abf78a1695f7df406c", + "url": "https://api.github.com/repos/josemmo/Facturae-PHP/zipball/c7f01f5d00a82bcaa1bdb9cfe7029cc7d8296fc4", + "reference": "c7f01f5d00a82bcaa1bdb9cfe7029cc7d8296fc4", "shasum": "" }, "require": { @@ -5523,9 +5523,9 @@ ], "support": { "issues": "https://github.com/josemmo/Facturae-PHP/issues", - "source": "https://github.com/josemmo/Facturae-PHP/tree/v1.8.0" + "source": "https://github.com/josemmo/Facturae-PHP/tree/v1.8.1" }, - "time": "2024-05-11T18:17:09+00:00" + "time": "2024-06-16T10:13:36+00:00" }, { "name": "kelunik/certificate", @@ -17354,16 +17354,16 @@ }, { "name": "friendsofphp/php-cs-fixer", - "version": "v3.58.1", + "version": "v3.59.3", "source": { "type": "git", "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", - "reference": "04e9424025677a86914b9a4944dbbf4060bb0aff" + "reference": "30ba9ecc2b0e5205e578fe29973c15653d9bfd29" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/04e9424025677a86914b9a4944dbbf4060bb0aff", - "reference": "04e9424025677a86914b9a4944dbbf4060bb0aff", + "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/30ba9ecc2b0e5205e578fe29973c15653d9bfd29", + "reference": "30ba9ecc2b0e5205e578fe29973c15653d9bfd29", "shasum": "" }, "require": { @@ -17393,16 +17393,16 @@ "symfony/stopwatch": "^5.4 || ^6.0 || ^7.0" }, "require-dev": { - "facile-it/paraunit": "^1.3 || ^2.0", - "infection/infection": "^0.27.11", + "facile-it/paraunit": "^1.3 || ^2.3", + "infection/infection": "^0.29.5", "justinrainbow/json-schema": "^5.2", "keradus/cli-executor": "^2.1", "mikey179/vfsstream": "^1.6.11", "php-coveralls/php-coveralls": "^2.7", "php-cs-fixer/accessible-object": "^1.1", - "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.4", - "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.4", - "phpunit/phpunit": "^9.6 || ^10.5.5 || ^11.0.2", + "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.5", + "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.5", + "phpunit/phpunit": "^9.6.19 || ^10.5.21 || ^11.2", "symfony/var-dumper": "^5.4 || ^6.0 || ^7.0", "symfony/yaml": "^5.4 || ^6.0 || ^7.0" }, @@ -17417,7 +17417,10 @@ "autoload": { "psr-4": { "PhpCsFixer\\": "src/" - } + }, + "exclude-from-classmap": [ + "src/Fixer/Internal/*" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -17442,7 +17445,7 @@ ], "support": { "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues", - "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.58.1" + "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.59.3" }, "funding": [ { @@ -17450,7 +17453,7 @@ "type": "github" } ], - "time": "2024-05-29T16:39:07+00:00" + "time": "2024-06-16T14:17:03+00:00" }, { "name": "hamcrest/hamcrest-php", @@ -18558,16 +18561,16 @@ }, { "name": "phpunit/phpunit", - "version": "10.5.20", + "version": "10.5.21", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "547d314dc24ec1e177720d45c6263fb226cc2ae3" + "reference": "ac837816fa52078f7a5e17ed774f256a72a51af6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/547d314dc24ec1e177720d45c6263fb226cc2ae3", - "reference": "547d314dc24ec1e177720d45c6263fb226cc2ae3", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/ac837816fa52078f7a5e17ed774f256a72a51af6", + "reference": "ac837816fa52078f7a5e17ed774f256a72a51af6", "shasum": "" }, "require": { @@ -18639,7 +18642,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.20" + "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.21" }, "funding": [ { @@ -18655,7 +18658,7 @@ "type": "tidelift" } ], - "time": "2024-04-24T06:32:35+00:00" + "time": "2024-06-15T09:13:15+00:00" }, { "name": "react/cache", @@ -20752,5 +20755,5 @@ "platform-dev": { "php": "^8.2" }, - "plugin-api-version": "2.6.0" + "plugin-api-version": "2.3.0" } From c163f3c1a4622dd235412a14deb58b69fec33f79 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Mon, 17 Jun 2024 20:38:33 +1000 Subject: [PATCH 07/15] Static Analysis --- .../Controllers/PurchaseOrderController.php | 2 +- .../Requests/Payment/StorePaymentRequest.php | 6 ++-- app/Import/Transformer/BaseTransformer.php | 6 ++-- app/Models/User.php | 1 + .../PayPal/PayPalBasePaymentDriver.php | 2 +- app/PaymentDrivers/Stripe/ACH.php | 2 -- app/PaymentDrivers/StripePaymentDriver.php | 6 +--- app/PaymentDrivers/WePayPaymentDriver.php | 2 +- .../Subscription/PaymentLinkService.php | 2 +- app/Services/Tax/Providers/TaxProvider.php | 2 +- .../gateways/paypal/ppcp/card.blade.php | 2 +- tests/Feature/PaymentTest.php | 32 +++++++++++++++++++ 12 files changed, 46 insertions(+), 19 deletions(-) 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/Requests/Payment/StorePaymentRequest.php b/app/Http/Requests/Payment/StorePaymentRequest.php index f3e8e33adfe8..f0e617a12eba 100644 --- a/app/Http/Requests/Payment/StorePaymentRequest.php +++ b/app/Http/Requests/Payment/StorePaymentRequest.php @@ -129,9 +129,9 @@ class StorePaymentRequest extends Request $input['date'] = now()->addSeconds($user->company()->utc_offset())->format('Y-m-d'); } - if (! isset($input['idempotency_key'])) { - $input['idempotency_key'] = substr(sha1(json_encode($input)).time()."{$input['date']}{$input['amount']}{$user->id}", 0, 64); - } + // if (! isset($input['idempotency_key'])) { + $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/Import/Transformer/BaseTransformer.php b/app/Import/Transformer/BaseTransformer.php index dbaa16d75c22..45c7fd8fca0c 100644 --- a/app/Import/Transformer/BaseTransformer.php +++ b/app/Import/Transformer/BaseTransformer.php @@ -653,11 +653,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`, ' ' ,'')) = ?", [ @@ -673,7 +673,7 @@ class BaseTransformer $ec->name = $name; $ec->save(); - return $ec ? $ec->id : null; + return $ec->id; } public function getOrCreateExpenseCategry($name) diff --git a/app/Models/User.php b/app/Models/User.php index e3c03c63ebf5..c10132696530 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -264,6 +264,7 @@ class User extends Authenticatable implements MustVerifyEmail { $truth = app()->make(TruthSource::class); + // @phpstan-ignore-next-line if ($this->company) { return $this->company; } elseif ($truth->getCompany()) { diff --git a/app/PaymentDrivers/PayPal/PayPalBasePaymentDriver.php b/app/PaymentDrivers/PayPal/PayPalBasePaymentDriver.php index 0db7ff2ac382..15b74889778c 100644 --- a/app/PaymentDrivers/PayPal/PayPalBasePaymentDriver.php +++ b/app/PaymentDrivers/PayPal/PayPalBasePaymentDriver.php @@ -194,7 +194,7 @@ class PayPalBasePaymentDriver extends BaseDriver { return ''; - /** @var \App\Models\ClientGatewayToken $cgt */ + /** @var ?\App\Models\ClientGatewayToken $cgt */ $cgt = ClientGatewayToken::where('company_gateway_id', $this->company_gateway->id) ->where('client_id', $this->client->id) ->first(); diff --git a/app/PaymentDrivers/Stripe/ACH.php b/app/PaymentDrivers/Stripe/ACH.php index b21641609476..2802835bc69e 100644 --- a/app/PaymentDrivers/Stripe/ACH.php +++ b/app/PaymentDrivers/Stripe/ACH.php @@ -344,8 +344,6 @@ class ACH return redirect()->route('client.payment_methods.verification', ['payment_method' => $cgt->hashed_id, 'method' => GatewayType::BANK_TRANSFER]); - $data['message'] = 'Invalid parameters were supplied to Stripe\'s API'; - break; case $e instanceof AuthenticationException: $data['message'] = 'Authentication with Stripe\'s API failed'; break; diff --git a/app/PaymentDrivers/StripePaymentDriver.php b/app/PaymentDrivers/StripePaymentDriver.php index 3b3a2047d4ef..cb3b0584d4e6 100644 --- a/app/PaymentDrivers/StripePaymentDriver.php +++ b/app/PaymentDrivers/StripePaymentDriver.php @@ -489,11 +489,7 @@ class StripePaymentDriver extends BaseDriver { $customer = Customer::retrieve($customer_id, $this->stripe_connect_auth); - if ($customer) { - return $customer; - } - - return null; + return $customer ?? null; } /** diff --git a/app/PaymentDrivers/WePayPaymentDriver.php b/app/PaymentDrivers/WePayPaymentDriver.php index 20daa4b410e1..2cf8fd4979a3 100644 --- a/app/PaymentDrivers/WePayPaymentDriver.php +++ b/app/PaymentDrivers/WePayPaymentDriver.php @@ -53,7 +53,7 @@ class WePayPaymentDriver extends BaseDriver throw new \Exception("Gateway no longer supported", 500); - return $this; + // return $this; } /** diff --git a/app/Services/Subscription/PaymentLinkService.php b/app/Services/Subscription/PaymentLinkService.php index 2d91260e7e2c..1c66db998ff4 100644 --- a/app/Services/Subscription/PaymentLinkService.php +++ b/app/Services/Subscription/PaymentLinkService.php @@ -117,7 +117,7 @@ class PaymentLinkService /* 06-04-2022 */ /* We may not be in a state where the user is present */ - if (auth()->guard('contact')) { + if (auth()->guard('contact')->user()) { return $this->handleRedirect('/client/invoices/' . $this->encodePrimaryKey($payment_hash->fee_invoice_id)); } } diff --git a/app/Services/Tax/Providers/TaxProvider.php b/app/Services/Tax/Providers/TaxProvider.php index 44585c75bb25..1a4b20736542 100644 --- a/app/Services/Tax/Providers/TaxProvider.php +++ b/app/Services/Tax/Providers/TaxProvider.php @@ -227,7 +227,7 @@ class TaxProvider // $this->provider = EuTax::class; - return $this; + // return $this; } /** diff --git a/resources/views/portal/ninja2020/gateways/paypal/ppcp/card.blade.php b/resources/views/portal/ninja2020/gateways/paypal/ppcp/card.blade.php index 38db67ac5138..b740e554157a 100644 --- a/resources/views/portal/ninja2020/gateways/paypal/ppcp/card.blade.php +++ b/resources/views/portal/ninja2020/gateways/paypal/ppcp/card.blade.php @@ -88,7 +88,7 @@ @if(isset($merchantId)) - + @else @endif 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() { From e469bee62068ec66ebddaa16f8917fef42ecaf5b Mon Sep 17 00:00:00 2001 From: David Bomba Date: Mon, 17 Jun 2024 20:47:53 +1000 Subject: [PATCH 08/15] improve idempotency --- tests/Feature/MultiPaymentDeleteTest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/Feature/MultiPaymentDeleteTest.php b/tests/Feature/MultiPaymentDeleteTest.php index 72c5e3640ac6..8a75edaeb78d 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([ From a25368986f3fd60c59e9dee8aa820d31a9cdc2d7 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Mon, 17 Jun 2024 21:09:34 +1000 Subject: [PATCH 09/15] add delays for payments post --- tests/Feature/MultiPaymentDeleteTest.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/Feature/MultiPaymentDeleteTest.php b/tests/Feature/MultiPaymentDeleteTest.php index 8a75edaeb78d..a1a2dc3b5879 100644 --- a/tests/Feature/MultiPaymentDeleteTest.php +++ b/tests/Feature/MultiPaymentDeleteTest.php @@ -220,6 +220,7 @@ class MultiPaymentDeleteTest extends TestCase $this->assertEquals(162, $invoice->client->fresh()->balance); $this->assertEquals(163, $invoice->client->fresh()->paid_to_date); + usleep(800); // Pay 162 again and create payment #3 $data = [ @@ -233,6 +234,7 @@ class MultiPaymentDeleteTest extends TestCase ], ], 'date' => '2019/12/12', + 'idempotency_key' => md5(time()), ]; $response = $this->withHeaders([ From 4ef2d99ca9092253c12ac0d8e93102455085931a Mon Sep 17 00:00:00 2001 From: David Bomba Date: Mon, 17 Jun 2024 21:18:06 +1000 Subject: [PATCH 10/15] add delays for payments post --- tests/Feature/MultiPaymentDeleteTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Feature/MultiPaymentDeleteTest.php b/tests/Feature/MultiPaymentDeleteTest.php index a1a2dc3b5879..1b73e583495e 100644 --- a/tests/Feature/MultiPaymentDeleteTest.php +++ b/tests/Feature/MultiPaymentDeleteTest.php @@ -220,7 +220,7 @@ class MultiPaymentDeleteTest extends TestCase $this->assertEquals(162, $invoice->client->fresh()->balance); $this->assertEquals(163, $invoice->client->fresh()->paid_to_date); - usleep(800); + sleep(1); // Pay 162 again and create payment #3 $data = [ From f03c6a1d6b7816ed6f50a1bfbaea8ae1e72a1587 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Mon, 17 Jun 2024 21:29:31 +1000 Subject: [PATCH 11/15] Roll back for idempotency --- app/Http/Requests/Payment/StorePaymentRequest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/Http/Requests/Payment/StorePaymentRequest.php b/app/Http/Requests/Payment/StorePaymentRequest.php index f0e617a12eba..34bba9f648af 100644 --- a/app/Http/Requests/Payment/StorePaymentRequest.php +++ b/app/Http/Requests/Payment/StorePaymentRequest.php @@ -129,9 +129,9 @@ class StorePaymentRequest extends Request $input['date'] = now()->addSeconds($user->company()->utc_offset())->format('Y-m-d'); } - // if (! isset($input['idempotency_key'])) { + if (! isset($input['idempotency_key'])) { $input['idempotency_key'] = substr(time()."{$input['date']}{$input['amount']}{$credits_total}{$this->client_id}{$user->company()->company_key}", 0, 64); - // } + } $this->replace($input); } From 957ddb2a818c22352066d763f1e0c94fef8ae7c3 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Tue, 18 Jun 2024 09:36:22 +1000 Subject: [PATCH 12/15] Fixes for wave imports --- app/Filters/ExpenseFilters.php | 2 +- .../Transformer/Wave/InvoiceTransformer.php | 2 +- app/Models/BaseModel.php | 7 +++- lang/en/texts.php | 36 ++----------------- 4 files changed, 10 insertions(+), 37 deletions(-) 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/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/Models/BaseModel.php b/app/Models/BaseModel.php index 727b2adfe19d..065e3c577cb2 100644 --- a/app/Models/BaseModel.php +++ b/app/Models/BaseModel.php @@ -374,7 +374,12 @@ class BaseModel extends Model $files->push($company_docs); - $pdf = (new PdfMerge($files->flatten()->toArray()))->run(); + try{ + $pdf = (new PdfMerge($files->flatten()->toArray()))->run(); + } + catch(\Exception $e){ + nlog("Exception:: BaseModel:: PdfMerge::" . $e->getMessage()); + } return $pdf; } diff --git a/lang/en/texts.php b/lang/en/texts.php index 4ade52e4d5ec..758575e06cdf 100644 --- a/lang/en/texts.php +++ b/lang/en/texts.php @@ -2934,13 +2934,6 @@ $lang = array( 'mime_types' => 'Mime types', 'mime_types_placeholder' => '.pdf , .docx, .jpg', 'mime_types_help' => 'Comma separated list of allowed mime types, leave blank for all', - 'ticket_number_start_help' => 'Ticket number must be greater than the current ticket number', - 'new_ticket_template_id' => 'New ticket', - 'new_ticket_autoresponder_help' => 'Selecting a template will send an auto response to a client/contact when a new ticket is created', - 'update_ticket_template_id' => 'Updated ticket', - 'update_ticket_autoresponder_help' => 'Selecting a template will send an auto response to a client/contact when a ticket is updated', - 'close_ticket_template_id' => 'Closed ticket', - 'close_ticket_autoresponder_help' => 'Selecting a template will send an auto response to a client/contact when a ticket is closed', 'default_priority' => 'Default priority', 'alert_new_comment_id' => 'New comment', 'alert_comment_ticket_help' => 'Selecting a template will send a notification (to agent) when a comment is made.', @@ -2957,8 +2950,6 @@ $lang = array( 'alert_ticket_overdue_email' => 'Additional overdue ticket notifications', 'alert_ticket_overdue_email_help' => 'Comma separated emails to bcc on ticket overdue.', 'alert_ticket_overdue_agent_id_help' => 'Selecting a template will send a notification (to agent) when a ticket becomes overdue.', - 'ticket_master' => 'Ticket Master', - 'ticket_master_help' => 'Has the ability to assign and transfer tickets. Assigned as the default agent for all tickets.', 'default_agent' => 'Default Agent', 'default_agent_help' => 'If selected will automatically be assigned to all inbound tickets', 'show_agent_details' => 'Show agent details on responses', @@ -2966,43 +2957,19 @@ $lang = array( 'remove_avatar' => 'Remove avatar', 'ticket_not_found' => 'Ticket not found', 'add_template' => 'Add Template', - 'ticket_template' => 'Ticket Template', - 'ticket_templates' => 'Ticket Templates', 'updated_ticket_template' => 'Updated Ticket Template', 'created_ticket_template' => 'Created Ticket Template', 'archive_ticket_template' => 'Archive Template', 'restore_ticket_template' => 'Restore Template', 'archived_ticket_template' => 'Successfully archived template', 'restored_ticket_template' => 'Successfully restored template', - 'close_reason' => 'Let us know why you are closing this ticket', - 'reopen_reason' => 'Let us know why you are reopening this ticket', 'enter_ticket_message' => 'Please enter a message to update the ticket', 'show_hide_all' => 'Show / Hide all', 'subject_required' => 'Subject required', 'mobile_refresh_warning' => 'If you\'re using the mobile app you may need to do a full refresh.', - 'enable_proposals_for_background' => 'To upload a background image :link to enable the proposals module.', - 'ticket_assignment' => 'Ticket :ticket_number has been assigned to :agent', - 'ticket_contact_reply' => 'Ticket :ticket_number has been updated by client :contact', - 'ticket_new_template_subject' => 'Ticket :ticket_number has been created.', - 'ticket_updated_template_subject' => 'Ticket :ticket_number has been updated.', - 'ticket_closed_template_subject' => 'Ticket :ticket_number has been closed.', - 'ticket_overdue_template_subject' => 'Ticket :ticket_number is now overdue', 'merge' => 'Merge', 'merged' => 'Merged', 'agent' => 'Agent', - 'parent_ticket' => 'Parent Ticket', - 'linked_tickets' => 'Linked Tickets', - 'merge_prompt' => 'Enter ticket number to merge into', - 'merge_from_to' => 'Ticket #:old_ticket merged into Ticket #:new_ticket', - 'merge_closed_ticket_text' => 'Ticket #:old_ticket was closed and merged into Ticket#:new_ticket - :subject', - 'merge_updated_ticket_text' => 'Ticket #:old_ticket was closed and merged into this ticket', - 'merge_placeholder' => 'Merge ticket #:ticket into the following ticket', - 'select_ticket' => 'Select Ticket', - 'new_internal_ticket' => 'New internal ticket', - 'internal_ticket' => 'Internal ticket', - 'create_ticket' => 'Create ticket', - 'allow_inbound_email_tickets_external' => 'New Tickets by email (Client)', - 'allow_inbound_email_tickets_external_help' => 'Allow clients to create new tickets by email', 'include_in_filter' => 'Include in filter', 'custom_client1' => ':VALUE', 'custom_client2' => ':VALUE', @@ -5334,7 +5301,8 @@ $lang = array( 'btcpay_refund_body' => 'A refund intended for you has been issued. To claim it via BTCPay, please click on this link:', 'currency_mauritanian_ouguiya' => 'Mauritanian Ouguiya', 'currency_bhutan_ngultrum' => 'Bhutan Ngultrum', - 'end_of_month' => 'End Of Month' + 'end_of_month' => 'End Of Month', + 'merge_e_invoice_to_pdf' => 'Merge E-Invoice and PDF', ); return $lang; \ No newline at end of file From f68d1d30537698ef60199e34117d516c66a71060 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Tue, 18 Jun 2024 09:41:22 +1000 Subject: [PATCH 13/15] Static Analysis --- app/Http/Requests/Preview/PreviewInvoiceRequest.php | 4 +++- app/PaymentDrivers/CheckoutCom/CheckoutWebhook.php | 1 + app/PaymentDrivers/PayPal/PayPalBasePaymentDriver.php | 1 + app/PaymentDrivers/PayPal/PayPalWebhook.php | 2 +- app/PaymentDrivers/Stripe/BankTransfer.php | 6 +++--- app/Services/Pdf/PdfBuilder.php | 1 + app/Services/Pdf/PdfMock.php | 3 ++- app/Services/Template/TemplateAction.php | 2 ++ 8 files changed, 14 insertions(+), 6 deletions(-) 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/PaymentDrivers/CheckoutCom/CheckoutWebhook.php b/app/PaymentDrivers/CheckoutCom/CheckoutWebhook.php index 1004319ee6fa..0873dbcdf94f 100644 --- a/app/PaymentDrivers/CheckoutCom/CheckoutWebhook.php +++ b/app/PaymentDrivers/CheckoutCom/CheckoutWebhook.php @@ -56,6 +56,7 @@ class CheckoutWebhook implements ShouldQueue nlog("Checkout Webhook type not set"); } + /** @phpstan-ignore-next-line */ match($this->webhook_array['type']) { 'payment_approved' => $this->paymentApproved(), }; diff --git a/app/PaymentDrivers/PayPal/PayPalBasePaymentDriver.php b/app/PaymentDrivers/PayPal/PayPalBasePaymentDriver.php index 15b74889778c..4e01c7582c0b 100644 --- a/app/PaymentDrivers/PayPal/PayPalBasePaymentDriver.php +++ b/app/PaymentDrivers/PayPal/PayPalBasePaymentDriver.php @@ -103,6 +103,7 @@ class PayPalBasePaymentDriver extends BaseDriver "25" => $method = PaymentType::VENMO, "28" => $method = PaymentType::PAY_LATER, "29" => $method = PaymentType::CREDIT_CARD_OTHER, + default => $method = PaymentType::PAYPAL, }; return $method; diff --git a/app/PaymentDrivers/PayPal/PayPalWebhook.php b/app/PaymentDrivers/PayPal/PayPalWebhook.php index 2840e5ccb4ce..701f2817c315 100644 --- a/app/PaymentDrivers/PayPal/PayPalWebhook.php +++ b/app/PaymentDrivers/PayPal/PayPalWebhook.php @@ -63,7 +63,7 @@ class PayPalWebhook implements ShouldQueue if($this->verifyWebhook()) { nlog('verified'); - match($this->webhook_request['event_type']) { + match($this->webhook_request['event_type']) {//@phpstan-ignore-line 'CHECKOUT.ORDER.COMPLETED' => $this->checkoutOrderCompleted(), }; diff --git a/app/PaymentDrivers/Stripe/BankTransfer.php b/app/PaymentDrivers/Stripe/BankTransfer.php index d5f02d085878..4f7a1bac4392 100644 --- a/app/PaymentDrivers/Stripe/BankTransfer.php +++ b/app/PaymentDrivers/Stripe/BankTransfer.php @@ -80,7 +80,7 @@ class BankTransfer */ private function resolveBankType() { - return match ($this->stripe->client->currency()->code) { + return match ($this->stripe->client->currency()->code) { //@phpstan-ignore-line 'GBP' => ['type' => 'gb_bank_transfer'], 'EUR' => ['type' => 'eu_bank_transfer', 'eu_bank_transfer' => ['country' => $this->stripe->client->country->iso_3166_2]], 'JPY' => ['type' => 'jp_bank_transfer'], @@ -128,8 +128,8 @@ class BankTransfer } /* Create a pending payment */ - if ($pi->status == 'requires_action' && $pi->next_action->type == 'display_bank_transfer_instructions') { - match ($pi->next_action->display_bank_transfer_instructions->currency) { + if ($pi->status == 'requires_action' && $pi->next_action->type == 'display_bank_transfer_instructions') { //@phpstan-ignore-line + match ($pi->next_action->display_bank_transfer_instructions->currency) { //@phpstan-ignore-line 'mxn' => $data['bank_details'] = $this->formatDataforMx($pi), 'gbp' => $data['bank_details'] = $this->formatDataforUk($pi), 'eur' => $data['bank_details'] = $this->formatDataforEur($pi), diff --git a/app/Services/Pdf/PdfBuilder.php b/app/Services/Pdf/PdfBuilder.php index 601bf2229d35..5af214dbd30a 100644 --- a/app/Services/Pdf/PdfBuilder.php +++ b/app/Services/Pdf/PdfBuilder.php @@ -993,6 +993,7 @@ class PdfBuilder PdfService::DELIVERY_NOTE => $this->getDeliveryNoteSections(), PdfService::STATEMENT => $this->getStatementSections(), PdfService::PURCHASE_ORDER => $this->getPurchaseOrderSections(), + default => $this->getProductSections(), }; } diff --git a/app/Services/Pdf/PdfMock.php b/app/Services/Pdf/PdfMock.php index 0173ab8c624e..7bc40ec22006 100644 --- a/app/Services/Pdf/PdfMock.php +++ b/app/Services/Pdf/PdfMock.php @@ -174,7 +174,8 @@ class PdfMock match ($this->request['settings_type']) { 'group' => $settings = ClientSettings::buildClientSettings($this->company->settings, $this->request['settings']), 'client' => $settings = ClientSettings::buildClientSettings($this->company->settings, $this->request['settings']), - 'company' => $settings = (object)$this->request['settings'] + 'company' => $settings = (object)$this->request['settings'], + default => $settings = (object)$this->request['settings'], }; $settings = CompanySettings::setProperties($settings); diff --git a/app/Services/Template/TemplateAction.php b/app/Services/Template/TemplateAction.php index 170b0cef7701..2a892ad2b0b2 100644 --- a/app/Services/Template/TemplateAction.php +++ b/app/Services/Template/TemplateAction.php @@ -102,6 +102,7 @@ class TemplateAction implements ShouldQueue Expense::class => $resource->with('client'), Payment::class => $resource->with('invoices', 'client'), Client::class => $resource, + default => $resource, }; $result = $resource->withTrashed() @@ -219,6 +220,7 @@ class TemplateAction implements ShouldQueue Project::class => 'projects', Client::class => 'clients', Vendor::class => 'vendors', + default =>'invoices', }; } From 006e819f3a7c340afc6fdae2cd8bb0dcd459c98b Mon Sep 17 00:00:00 2001 From: David Bomba Date: Tue, 18 Jun 2024 10:24:03 +1000 Subject: [PATCH 14/15] Refactor for cache statics moving to container --- .../RecurringExpenseToExpenseFactory.php | 10 ++- .../Transformer/TransactionTransformer.php | 20 ++--- .../Yodlee/Transformer/IncomeTransformer.php | 16 ++-- .../SubscriptionPurchaseController.php | 19 +++-- .../Requests/Client/StoreClientRequest.php | 46 ++++++------ .../Requests/Client/UpdateClientRequest.php | 28 +++---- .../Requests/Shop/StoreShopClientRequest.php | 20 +++-- app/Import/Transformer/BaseTransformer.php | 19 ++--- .../Authentication/RegisterOrLogin.php | 4 +- app/Livewire/BillingPortalPurchase.php | 24 ++++-- app/Livewire/BillingPortalPurchasev2.php | 23 ++++-- app/Models/Client.php | 36 +-------- app/Models/ClientContact.php | 12 ++- app/Models/Company.php | 64 +++++----------- app/Models/Vendor.php | 12 ++- app/Models/VendorContact.php | 8 +- .../Authorize/AuthorizeCustomer.php | 8 +- app/Providers/StaticServiceProvider.php | 19 +++-- app/Services/Chart/ChartService.php | 8 +- app/Services/Chart/ChartServiceLegacy.php | 8 +- app/Services/Pdf/PdfConfiguration.php | 12 ++- app/Utils/HtmlEngine.php | 39 ++++------ app/Utils/Statics.php | 75 ++++++++++++------- app/Utils/TranslationHelper.php | 30 ++++++-- app/Utils/VendorHtmlEngine.php | 28 ++----- 25 files changed, 292 insertions(+), 296 deletions(-) diff --git a/app/Factory/RecurringExpenseToExpenseFactory.php b/app/Factory/RecurringExpenseToExpenseFactory.php index de59952d871c..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); 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/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/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/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 45c7fd8fca0c..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 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/Models/Client.php b/app/Models/Client.php index c25df2f99419..f9a68fbe8ffc 100644 --- a/app/Models/Client.php +++ b/app/Models/Client.php @@ -378,15 +378,11 @@ class Client extends BaseModel implements HasLocalePreference public function language() { - $languages = app('languages'); - // $languages = Cache::get('languages'); - // if (! $languages) { - // $this->buildCache(true); - // } + /** @var \Illuminate\Support\Collection<\App\Models\Language> */ + $languages = app('languages'); return $languages->first(function ($item) { - /** @var \stdClass $item */ return $item->id == $this->getSetting('language_id'); }); } @@ -412,17 +408,10 @@ class Client extends BaseModel implements HasLocalePreference public function date_format() { - /** @var \Illuminate\Support\Collection $date_formats */ + /** @var \Illuminate\Support\Collection */ $date_formats = app('date_formats'); - // $date_formats = Cache::get('date_formats'); - - // if (! $date_formats) { - // $this->buildCache(true); - // } return $date_formats->first(function ($item) { - - /** @var \stdClass $item */ return $item->id == $this->getSetting('date_format_id'); })->format; } @@ -430,17 +419,10 @@ class Client extends BaseModel implements HasLocalePreference public function currency() { - /** @var \Illuminate\Support\Collection $currencies */ + /** @var \Illuminate\Support\Collection */ $currencies = app('currencies'); - // $currencies = Cache::get('currencies'); - - // if (! $currencies) { - // $this->buildCache(true); - // } return $currencies->first(function ($item) { - - /** @var \stdClass $item */ return $item->id == $this->getSetting('currency_id'); }); } @@ -751,16 +733,6 @@ class Client extends BaseModel implements HasLocalePreference public function preferredLocale() { $this->language()->locale ?? 'en'; - // $languages = app('languages'); - // $languages = Cache::get('languages'); - - // if (! $languages) { - // $this->buildCache(true); - // } - - // return $languages->first(function ($item) { - // return $item->id == $this->getSetting('language_id'); - // })->locale; } public function backup_path(): string diff --git a/app/Models/ClientContact.php b/app/Models/ClientContact.php index 33816d5c01d4..fd47d0e6feb0 100644 --- a/app/Models/ClientContact.php +++ b/app/Models/ClientContact.php @@ -271,15 +271,13 @@ class ClientContact extends Authenticatable implements HasLocalePreference public function preferredLocale() { - $languages = Cache::get('languages'); + + /** @var \Illuminate\Support\Collection<\App\Models\Language> */ + $languages = app('languages'); - if (! $languages) { - $this->buildCache(true); - } - - return $languages->filter(function ($item) { + return $languages->first(function ($item) { return $item->id == $this->client->getSetting('language_id'); - })->first()->locale; + })->locale; } public function routeNotificationForMail($notification) diff --git a/app/Models/Company.php b/app/Models/Company.php index c20d096c2453..8a0ef899de12 100644 --- a/app/Models/Company.php +++ b/app/Models/Company.php @@ -636,24 +636,13 @@ class Company extends BaseModel public function country() { + + /** @var \Illuminate\Support\Collection<\App\Models\Country> */ $countries = app('countries'); - // $countries = Cache::get('countries'); - - // if (! $companies) { - // $this->buildCache(true); - - // $companies = Cache::get('countries'); - // } - return $countries->first(function ($item) { - - /** @var \stdClass $item */ return $item->id == $this->getSetting('country_id'); }); - - // return $this->belongsTo(Country::class); - // return Country::find($this->settings->country_id); } public function group_settings() @@ -663,20 +652,14 @@ class Company extends BaseModel public function timezone() { - // $timezones = Cache::get('timezones'); + /** @var \Illuminate\Support\Collection<\App\Models\TimeZone> */ $timezones = app('timezones'); - // if (! $timezones) { - // $this->buildCache(true); - // } - return $timezones->first(function ($item) { - /** @var \stdClass $item */ return $item->id == $this->settings->timezone_id; }); - // return Timezone::find($this->settings->timezone_id); } public function designs() @@ -701,22 +684,15 @@ class Company extends BaseModel public function language() { - $languages = Cache::get('languages'); + + /** @var \Illuminate\Support\Collection<\App\Models\Language> */ + $languages = app('languages'); - //build cache and reinit - if (! $languages) { - $this->buildCache(true); - $languages = Cache::get('languages'); - } - - //if the cache is still dead, get from DB - if (!$languages && property_exists($this->settings, 'language_id')) { - return Language::find($this->settings->language_id); - } - - return $languages->filter(function ($item) { + $language = $languages->first(function ($item) { return $item->id == $this->settings->language_id; - })->first(); + }); + + return $language ?? $languages->first(); } public function getLocale() @@ -757,11 +733,13 @@ class Company extends BaseModel public function currency() { - $currencies = Cache::get('currencies'); + + /** @var \Illuminate\Support\Collection<\App\Models\Currency> */ + $currencies = app('currencies'); - return $currencies->filter(function ($item) { + return $currencies->first(function ($item) { return $item->id == $this->settings->currency_id; - })->first(); + }); } /** @@ -974,15 +952,13 @@ class Company extends BaseModel public function date_format() { - $date_formats = Cache::get('date_formats'); + + /** @var \Illuminate\Support\Collection<\App\Models\DateFormat> */ + $date_formats = app('date_formats'); - if (! $date_formats) { - $this->buildCache(true); - } - - return $date_formats->filter(function ($item) { + return $date_formats->first(function ($item) { return $item->id == $this->getSetting('date_format_id'); - })->first()->format; + })->format; } public function getInvoiceCert() diff --git a/app/Models/Vendor.php b/app/Models/Vendor.php index a07980508c5a..7c7cc24985d6 100644 --- a/app/Models/Vendor.php +++ b/app/Models/Vendor.php @@ -177,19 +177,17 @@ class Vendor extends BaseModel public function currency() { - $currencies = Cache::get('currencies'); - - if (! $currencies) { - $this->buildCache(true); - } + + /** @var \Illuminate\Support\Collection<\App\Models\Currency> */ + $currencies = app('currencies'); if (! $this->currency_id) { return $this->company->currency(); } - return $currencies->filter(function ($item) { + return $currencies->first(function ($item) { return $item->id == $this->currency_id; - })->first(); + }); } public function timezone() diff --git a/app/Models/VendorContact.php b/app/Models/VendorContact.php index c04f53541f64..156928f80031 100644 --- a/app/Models/VendorContact.php +++ b/app/Models/VendorContact.php @@ -183,11 +183,13 @@ class VendorContact extends Authenticatable implements HasLocalePreference public function preferredLocale() { - $languages = Cache::get('languages'); + + /** @var \Illuminate\Support\Collection<\App\Models\Language> */ + $languages = app('languages'); - return $languages->filter(function ($item) { + return $languages->first(function ($item) { return $item->id == $this->company->getSetting('language_id'); - })->first()->locale; + })->locale; } /** diff --git a/app/PaymentDrivers/Authorize/AuthorizeCustomer.php b/app/PaymentDrivers/Authorize/AuthorizeCustomer.php index 253a016b4b7e..887da45dd801 100644 --- a/app/PaymentDrivers/Authorize/AuthorizeCustomer.php +++ b/app/PaymentDrivers/Authorize/AuthorizeCustomer.php @@ -161,11 +161,13 @@ class AuthorizeCustomer 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; } diff --git a/app/Providers/StaticServiceProvider.php b/app/Providers/StaticServiceProvider.php index 523a92e08c0b..5cdd13a58ff0 100644 --- a/app/Providers/StaticServiceProvider.php +++ b/app/Providers/StaticServiceProvider.php @@ -33,56 +33,61 @@ class StaticServiceProvider extends ServiceProvider */ public function register() { - - + /** @return \Illuminate\Support\Collection */ app()->singleton('currencies', function ($app) { return Currency::query()->orderBy('name')->get(); }); + /** @return \Illuminate\Support\Collection */ app()->singleton('languages', function ($app) { return Language::query()->orderBy('name')->get(); }); + /** @return \Illuminate\Support\Collection */ app()->singleton('countries', function ($app) { return Country::query()->orderBy('name')->get(); }); + /** @return \Illuminate\Support\Collection */ app()->singleton('payment_types', function ($app) { return PaymentTerm::query()->orderBy('num_days')->get(); }); + /** @return \Illuminate\Support\Collection */ app()->singleton('industries', function ($app) { return Industry::query()->orderBy('name')->get(); }); + /** @return \Illuminate\Support\Collection */ app()->singleton('banks', function ($app) { return Bank::query()->orderBy('name')->get(); }); + /** @return \Illuminate\Support\Collection */ app()->singleton('date_formats', function ($app) { return DateFormat::query()->orderBy('id')->get(); }); + /** @return \Illuminate\Support\Collection */ app()->singleton('timezones', function ($app) { return Timezone::query()->orderBy('id')->get(); }); - + + /** @return \Illuminate\Support\Collection */ app()->singleton('gateways', function ($app) { return Gateway::query()->orderBy('id')->get(); }); + /** @return \Illuminate\Support\Collection */ app()->singleton('industries', function ($app) { return Industry::query()->orderBy('id')->get(); }); + /** @return \Illuminate\Support\Collection */ app()->singleton('sizes', function ($app) { return Size::query()->orderBy('id')->get(); }); - /** @deprecated */ - app()->singleton('banks', function ($app) { - return Bank::query()->orderBy('id')->get(); - }); app()->singleton('templates', function ($app) { return [ diff --git a/app/Services/Chart/ChartService.php b/app/Services/Chart/ChartService.php index b6178436dbcb..7bd2ed911a0b 100644 --- a/app/Services/Chart/ChartService.php +++ b/app/Services/Chart/ChartService.php @@ -57,7 +57,9 @@ class ChartService /* Merge and filter by unique */ $currencies = $currencies->merge($expense_currencies)->unique(); - $cache_currencies = Cache::get('currencies'); + + /** @var \Illuminate\Support\Collection<\App\Models\Currency> */ + $cache_currencies = app('currencies'); $filtered_currencies = $cache_currencies->whereIn('id', $currencies)->all(); @@ -162,7 +164,9 @@ class ChartService private function addCurrencyCodes($data_set): array { - $currencies = Cache::get('currencies'); + + /** @var \Illuminate\Support\Collection<\App\Models\Currency> */ + $currencies = app('currencies'); foreach ($data_set as $key => $value) { $data_set[$key]->currency_id = str_replace('"', '', $value->currency_id); diff --git a/app/Services/Chart/ChartServiceLegacy.php b/app/Services/Chart/ChartServiceLegacy.php index bebc45bc3363..84b839ac11da 100644 --- a/app/Services/Chart/ChartServiceLegacy.php +++ b/app/Services/Chart/ChartServiceLegacy.php @@ -53,7 +53,9 @@ class ChartServiceLegacy /* Merge and filter by unique */ $currencies = $currencies->merge($expense_currencies)->unique(); - $cache_currencies = Cache::get('currencies'); + + /** @var \Illuminate\Support\Collection<\App\Models\Currency> */ + $cache_currencies = app('currencies'); $filtered_currencies = $cache_currencies->whereIn('id', $currencies)->all(); @@ -135,7 +137,9 @@ class ChartServiceLegacy private function addCurrencyCodes($data_set): array { - $currencies = Cache::get('currencies'); + + /** @var \Illuminate\Support\Collection<\App\Models\Currency> */ + $currencies = app('currencies'); foreach ($data_set as $key => $value) { $data_set[$key]->currency_id = str_replace('"', '', $value->currency_id); diff --git a/app/Services/Pdf/PdfConfiguration.php b/app/Services/Pdf/PdfConfiguration.php index df6c9d38537b..fddbc0766ae2 100644 --- a/app/Services/Pdf/PdfConfiguration.php +++ b/app/Services/Pdf/PdfConfiguration.php @@ -457,15 +457,13 @@ class PdfConfiguration */ public function setDateFormat(): self { - $date_formats = Cache::get('date_formats'); + + /** @var \Illuminate\Support\Collection<\App\Models\DateFormat> */ + $date_formats = app('date_formats'); - if (! $date_formats) { - $this->buildCache(true); - } - - $this->date_format = $date_formats->filter(function ($item) { + $this->date_format = $date_formats->first(function ($item) { return $item->id == $this->settings->date_format_id; - })->first()->format; + })->format; return $this; } diff --git a/app/Utils/HtmlEngine.php b/app/Utils/HtmlEngine.php index 5efa54297ccf..073d7d55b882 100644 --- a/app/Utils/HtmlEngine.php +++ b/app/Utils/HtmlEngine.php @@ -918,39 +918,30 @@ class HtmlEngine private function getCountryName(): string { - $countries = Cache::get('countries'); + + /** @var \Illuminate\Support\Collection<\App\Models\Country> */ + $countries = app('countries'); - if (! $countries) { - $this->buildCache(true); + $country = $countries->first(function ($item) { + return $item->id == $this->settings->country_id; + }); - $countries = Cache::get('countries'); - } - - if ($countries) { - $country = $countries->filter(function ($item) { - return $item->id == $this->settings->country_id; - })->first(); - } else { - $country = Country::find($this->settings->country_id); - } - - if ($country) { - return ctrans('texts.country_' . $country->name); - } - - return ' '; + return $country ? ctrans('texts.country_' . $country->name) : ctrans('texts.country_' . $countries->first()->name); } private function getCountryCode(): string { - $country = Country::find($this->settings->country_id); - if ($country) { - return $country->iso_3166_2; - } - return ' '; + /** @var \Illuminate\Support\Collection<\App\Models\Country> */ + $countries = app('countries'); + + $country = $countries->first(function ($item) { + return $item->id == $this->settings->country_id; + }); + + return $country ? $country->iso_3166_2 : ' '; } /** * Due to the way we are compiling the blade template we diff --git a/app/Utils/Statics.php b/app/Utils/Statics.php index e4b2201db658..aa8021c3d8e5 100644 --- a/app/Utils/Statics.php +++ b/app/Utils/Statics.php @@ -69,62 +69,81 @@ class Statics { $data = []; - foreach (config('ninja.cached_tables') as $name => $class) { - if (! Cache::has($name)) { - // check that the table exists in case the migration is pending - if (! Schema::hasTable((new $class())->getTable())) { - continue; - } - if ($name == 'payment_terms') { - $orderBy = 'num_days'; - } elseif ($name == 'fonts') { - $orderBy = 'sort_order'; - } elseif (in_array($name, ['currencies', 'industries', 'languages', 'countries', 'banks'])) { - $orderBy = 'name'; - } else { - $orderBy = 'id'; - } - $tableData = $class::orderBy($orderBy)->get(); - if ($tableData->count()) { - Cache::forever($name, $tableData); - } - } + // foreach (config('ninja.cached_tables') as $name => $class) { + // if (! Cache::has($name)) { + // // check that the table exists in case the migration is pending + // if (! Schema::hasTable((new $class())->getTable())) { + // continue; + // } + // if ($name == 'payment_terms') { + // $orderBy = 'num_days'; + // } elseif ($name == 'fonts') { + // $orderBy = 'sort_order'; + // } elseif (in_array($name, ['currencies', 'industries', 'languages', 'countries', 'banks'])) { + // $orderBy = 'name'; + // } else { + // $orderBy = 'id'; + // } + // $tableData = $class::orderBy($orderBy)->get(); + // if ($tableData->count()) { + // Cache::forever($name, $tableData); + // } + // } - $data[$name] = Cache::get($name); - } + // $data[$name] = app($name); + // } if ($locale) { - $data['industries'] = Cache::get('industries')->each(function ($industry) { + + /** @var \Illuminate\Support\Collection<\App\Models\Industry> */ + $industries = app('industries'); + + $data['industries'] = $industries->each(function ($industry) { $industry->name = ctrans('texts.industry_'.$industry->name); })->sortBy(function ($industry) { return $industry->name; })->values(); - $data['countries'] = Cache::get('countries')->each(function ($country) { + /** @var \Illuminate\Support\Collection<\App\Models\Country> */ + $countries = app('countries'); + + $data['countries'] = $countries->each(function ($country) { $country->name = ctrans('texts.country_'.$country->name); })->sortBy(function ($country) { return $country->name; })->values(); - $data['payment_types'] = Cache::get('payment_types')->each(function ($pType) { + + /** @var \Illuminate\Support\Collection<\App\Models\PaymentType> */ + $payment_types = app('payment_types'); + + $data['payment_types'] = $payment_types->each(function ($pType) { $pType->name = ctrans('texts.payment_type_'.$pType->name); })->sortBy(function ($pType) { return $pType->name; })->values(); - $data['languages'] = Cache::get('languages')->each(function ($lang) { + + /** @var \Illuminate\Support\Collection<\App\Models\Language> */ + $payment_types = app('languages'); + + $data['languages'] = $payment_types->each(function ($lang) { $lang->name = ctrans('texts.lang_'.$lang->name); })->sortBy(function ($lang) { return $lang->name; })->values(); - $data['currencies'] = Cache::get('currencies')->each(function ($currency) { + + /** @var \Illuminate\Support\Collection<\App\Models\Currency> */ + $currencies = app('currencies'); + + $data['currencies'] = $currencies->each(function ($currency) { $currency->name = ctrans('texts.currency_'.Str::slug($currency->name, '_')); })->sortBy(function ($currency) { return $currency->name; })->values(); - $data['templates'] = Cache::get('templates'); + $data['templates'] = app('templates'); } $data['bulk_updates'] = [ diff --git a/app/Utils/TranslationHelper.php b/app/Utils/TranslationHelper.php index 71ebec95f9e4..19793aad897f 100644 --- a/app/Utils/TranslationHelper.php +++ b/app/Utils/TranslationHelper.php @@ -19,7 +19,11 @@ class TranslationHelper { public static function getIndustries() { - return Cache::get('industries')->each(function ($industry) { + + /** @var \Illuminate\Support\Collection<\App\Models\Currency> */ + $industries = app('industries'); + + return $industries->each(function ($industry) { $industry->name = ctrans('texts.industry_'.$industry->name); })->sortBy(function ($industry) { return $industry->name; @@ -28,7 +32,11 @@ class TranslationHelper public static function getCountries() { - return Cache::get('countries')->each(function ($country) { + + /** @var \Illuminate\Support\Collection<\App\Models\Country> */ + $countries = app('countries'); + + return $countries->each(function ($country) { $country->name = ctrans('texts.country_'.$country->name); })->sortBy(function ($country) { return $country->iso_3166_2; @@ -37,7 +45,11 @@ class TranslationHelper public static function getPaymentTypes() { - return Cache::get('payment_types')->each(function ($pType) { + + /** @var \Illuminate\Support\Collection<\App\Models\PaymentType> */ + $payment_types = app('payment_types'); + + return $payment_types->each(function ($pType) { $pType->name = ctrans('texts.payment_type_'.$pType->name); })->sortBy(function ($pType) { return $pType->name; @@ -46,7 +58,11 @@ class TranslationHelper public static function getLanguages() { - return Cache::get('languages')->each(function ($lang) { + + /** @var \Illuminate\Support\Collection<\App\Models\Language> */ + $languages = app('languages'); + + return $languages->each(function ($lang) { $lang->name = ctrans('texts.lang_'.$lang->name); })->sortBy(function ($lang) { return $lang->name; @@ -55,7 +71,11 @@ class TranslationHelper public static function getCurrencies() { - return Cache::get('currencies')->each(function ($currency) { + + /** @var \Illuminate\Support\Collection<\App\Models\Currency> */ + $currencies = app('currencies'); + + return $currencies->each(function ($currency) { $currency->name = ctrans('texts.currency_'.Str::slug($currency->name, '_')); })->sortBy(function ($currency) { return $currency->name; diff --git a/app/Utils/VendorHtmlEngine.php b/app/Utils/VendorHtmlEngine.php index 1d8939617831..1b2b435df2c2 100644 --- a/app/Utils/VendorHtmlEngine.php +++ b/app/Utils/VendorHtmlEngine.php @@ -567,27 +567,15 @@ class VendorHtmlEngine private function getCountryName(): string { - $countries = Cache::get('countries'); + + /** @var \Illuminate\Support\Collection<\App\Models\Country> */ + $countries = app('countries'); - if (! $countries) { - $this->buildCache(true); - - $countries = Cache::get('countries'); - } - - if ($countries) { - $country = $countries->filter(function ($item) { - return $item->id == $this->settings->country_id; - })->first(); - } else { - $country = Country::find($this->settings->country_id); - } - - if ($country) { - return ctrans('texts.country_' . $country->name); - } - - return ' '; + $country = $countries->first(function ($item) { + return $item->id == $this->settings->country_id; + }); + + return $country ? ctrans('texts.country_' . $country->name) : ' '; } From dfdfc41fee09f65a79ebddad7e44aa127d635dee Mon Sep 17 00:00:00 2001 From: David Bomba Date: Tue, 18 Jun 2024 10:25:56 +1000 Subject: [PATCH 15/15] Static Analysis --- app/Services/Template/TemplateService.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/Services/Template/TemplateService.php b/app/Services/Template/TemplateService.php index 7df008689d3a..44f02d9b82a0 100644 --- a/app/Services/Template/TemplateService.php +++ b/app/Services/Template/TemplateService.php @@ -306,9 +306,6 @@ class TemplateService } catch(SyntaxError $e) { nlog($e->getMessage()); throw ($e); - } catch(Error $e) { - nlog("error = " . $e->getMessage()); - throw ($e); } catch(RuntimeError $e) { nlog("runtime = " . $e->getMessage()); throw ($e); @@ -318,8 +315,11 @@ class TemplateService } catch(SecurityError $e) { nlog("security = " . $e->getMessage()); throw ($e); + } catch(Error $e) { + nlog("error = " . $e->getMessage()); + throw ($e); } - + $template = $template->render($this->data); $f = $this->document->createDocumentFragment();