From 6192e014c62dbd227eb3aa22eacf5454ab06c145 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Fri, 8 Dec 2023 12:11:53 +1100 Subject: [PATCH 01/26] Add case for transaction searches --- app/Filters/InvoiceFilters.php | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/app/Filters/InvoiceFilters.php b/app/Filters/InvoiceFilters.php index a3feeb040047..08a6e5c6923f 100644 --- a/app/Filters/InvoiceFilters.php +++ b/app/Filters/InvoiceFilters.php @@ -147,15 +147,22 @@ class InvoiceFilters extends QueryFilters public function upcoming(): Builder { return $this->builder->whereIn('status_id', [Invoice::STATUS_PARTIAL, Invoice::STATUS_SENT]) - ->whereNull('due_date') - ->orWhere(function ($q) { - $q->where('due_date', '>=', now()->startOfDay()->subSecond())->where('partial', 0); - }) - ->orWhere(function ($q) { - $q->where('partial_due_date', '>=', now()->startOfDay()->subSecond())->where('partial', '>', 0); - }) - ->orderByRaw('ISNULL(due_date), due_date '. 'desc') - ->orderByRaw('ISNULL(partial_due_date), partial_due_date '. 'desc'); + ->where('is_deleted', 0) + ->where('balance', '>', 0) + ->where(function ($query) { + + $query->whereNull('due_date') + ->orWhere(function ($q) { + $q->where('due_date', '>=', now()->startOfDay()->subSecond())->where('partial', 0); + }) + ->orWhere(function ($q) { + $q->where('partial_due_date', '>=', now()->startOfDay()->subSecond())->where('partial', '>', 0); + }); + + }) + ->orderByRaw('ISNULL(due_date), due_date '. 'desc') + ->orderByRaw('ISNULL(partial_due_date), partial_due_date '. 'desc'); + } /** From ddcaead160e04bce9a867f825c97542dc2cb8c64 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Fri, 8 Dec 2023 12:57:34 +1100 Subject: [PATCH 02/26] Add checks for subdomain validation --- app/DataProviders/Domains.php | 3 ++- app/Http/Controllers/SubdomainController.php | 6 ++++++ tests/Unit/DomainCheckTest.php | 16 ++++++++++++++-- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/app/DataProviders/Domains.php b/app/DataProviders/Domains.php index 814baeebad0f..84ef923ed259 100644 --- a/app/DataProviders/Domains.php +++ b/app/DataProviders/Domains.php @@ -12,7 +12,8 @@ namespace App\DataProviders; -class Domains { +class Domains +{ private static array $verify_domains = [ '0-00.usa.cc', diff --git a/app/Http/Controllers/SubdomainController.php b/app/Http/Controllers/SubdomainController.php index 3800935ac85c..902fe115cfe7 100644 --- a/app/Http/Controllers/SubdomainController.php +++ b/app/Http/Controllers/SubdomainController.php @@ -30,6 +30,12 @@ class SubdomainController extends BaseController return response()->json(['message' => ctrans('texts.subdomain_is_not_available')], 401); } + + if (!preg_match('/^[A-Za-z0-9](?:[A-Za-z0-9\-]{0,61}[A-Za-z0-9])?$/', request()->input('subdomain'))) { + return response()->json(['message' => ctrans('texts.subdomain_is_not_available')], 401); + } + + return response()->json(['message' => 'Domain available'], 200); } } diff --git a/tests/Unit/DomainCheckTest.php b/tests/Unit/DomainCheckTest.php index 81bf7fd07757..ccd51be7deb4 100644 --- a/tests/Unit/DomainCheckTest.php +++ b/tests/Unit/DomainCheckTest.php @@ -28,8 +28,20 @@ class DomainCheckTest extends TestCase public function testDomainCheck() { - $this->assertTrue(in_array('yopmail.com', Domains::getDomains())); - $this->assertFalse(in_array('invoiceninja.com', Domains::getDomains())); + $this->assertTrue(in_array('yopmail.com', \App\DataProviders\Domains::getDomains())); + $this->assertFalse(in_array('invoiceninja.com', \App\DataProviders\Domains::getDomains())); } + + public function testSubdomainValidation() + { + $this->assertFalse($this->checker('invoiceninja')); + $this->assertFalse($this->checker('hello')); + $this->assertTrue($this->checker('nasty.pasty')); + } + + public function checker($subdomain) + { + return (!preg_match('/^[A-Za-z0-9](?:[A-Za-z0-9\-]{0,61}[A-Za-z0-9])?$/', $subdomain)); + } } From 82bcd84c4300a38286db61337fa6de4e10262185 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Fri, 8 Dec 2023 22:59:55 +1100 Subject: [PATCH 03/26] Set appropriate date format for payment factory --- app/Http/Controllers/PaymentController.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/Http/Controllers/PaymentController.php b/app/Http/Controllers/PaymentController.php index 10b8af7dcb38..951b2a3c77e1 100644 --- a/app/Http/Controllers/PaymentController.php +++ b/app/Http/Controllers/PaymentController.php @@ -155,6 +155,7 @@ class PaymentController extends BaseController $user = auth()->user(); $payment = PaymentFactory::create($user->company()->id, $user->id); + $payment->date = now()->addSeconds($user->company()->utc_offset())->format('Y-m-d'); return $this->itemResponse($payment); } From 6727f602a1b25d825ad2ecd3a7e6db8cea18f4a7 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Sat, 9 Dec 2023 09:42:15 +1100 Subject: [PATCH 04/26] Twilio --- app/Http/Controllers/TwilioController.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/Http/Controllers/TwilioController.php b/app/Http/Controllers/TwilioController.php index 39b7f726372c..c43ba09d7365 100644 --- a/app/Http/Controllers/TwilioController.php +++ b/app/Http/Controllers/TwilioController.php @@ -21,6 +21,7 @@ use Twilio\Rest\Client; class TwilioController extends BaseController { + public function __construct() { parent::__construct(); @@ -38,6 +39,10 @@ class TwilioController extends BaseController $account = $user->company()->account; + if(stripos($request->phone, '+21') !== false) { + return response()->json(['message' => 'This phone number is not supported'], 400); + } + if (MultiDB::hasPhoneNumber($request->phone)) { return response()->json(['message' => 'This phone number has already been verified with another account'], 400); } From 1f2d608742753882604bd8e9b0115e5ca704e112 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Sat, 9 Dec 2023 11:03:31 +1100 Subject: [PATCH 05/26] fixes for upcoming --- app/Filters/InvoiceFilters.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/Filters/InvoiceFilters.php b/app/Filters/InvoiceFilters.php index 08a6e5c6923f..f0ef5257bf32 100644 --- a/app/Filters/InvoiceFilters.php +++ b/app/Filters/InvoiceFilters.php @@ -153,10 +153,10 @@ class InvoiceFilters extends QueryFilters $query->whereNull('due_date') ->orWhere(function ($q) { - $q->where('due_date', '>=', now()->startOfDay()->subSecond())->where('partial', 0); + $q->where('due_date', '>=', now()->startOfDay()->subSecond())->where('partial', 0)->company(); }) ->orWhere(function ($q) { - $q->where('partial_due_date', '>=', now()->startOfDay()->subSecond())->where('partial', '>', 0); + $q->where('partial_due_date', '>=', now()->startOfDay()->subSecond())->where('partial', '>', 0)->company(); }); }) From 56fe16e5a8bbff1c533555898c06b5ef0bd01183 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Sat, 9 Dec 2023 11:27:24 +1100 Subject: [PATCH 06/26] Improvements for upcoming filters --- app/Filters/InvoiceFilters.php | 40 ++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/app/Filters/InvoiceFilters.php b/app/Filters/InvoiceFilters.php index f0ef5257bf32..df04af1d072a 100644 --- a/app/Filters/InvoiceFilters.php +++ b/app/Filters/InvoiceFilters.php @@ -146,22 +146,25 @@ class InvoiceFilters extends QueryFilters */ public function upcoming(): Builder { - return $this->builder->whereIn('status_id', [Invoice::STATUS_PARTIAL, Invoice::STATUS_SENT]) - ->where('is_deleted', 0) - ->where('balance', '>', 0) - ->where(function ($query) { - - $query->whereNull('due_date') - ->orWhere(function ($q) { - $q->where('due_date', '>=', now()->startOfDay()->subSecond())->where('partial', 0)->company(); - }) - ->orWhere(function ($q) { - $q->where('partial_due_date', '>=', now()->startOfDay()->subSecond())->where('partial', '>', 0)->company(); - }); - }) - ->orderByRaw('ISNULL(due_date), due_date '. 'desc') - ->orderByRaw('ISNULL(partial_due_date), partial_due_date '. 'desc'); + return $this->builder->where(function ($query) { + $query->whereIn('status_id', [Invoice::STATUS_PARTIAL, Invoice::STATUS_SENT]) + ->where('is_deleted', 0) + ->where('balance', '>', 0) + ->where(function ($query) { + + $query->whereNull('due_date') + ->orWhere(function ($q) { + $q->where('due_date', '>=', now()->startOfDay()->subSecond())->where('partial', 0); + }) + ->orWhere(function ($q) { + $q->where('partial_due_date', '>=', now()->startOfDay()->subSecond())->where('partial', '>', 0); + }); + + }) + ->orderByRaw('ISNULL(due_date), due_date ' . 'desc') + ->orderByRaw('ISNULL(partial_due_date), partial_due_date ' . 'desc'); + }); } @@ -172,13 +175,18 @@ class InvoiceFilters extends QueryFilters */ public function overdue(): Builder { - return $this->builder->whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL]) + return $this->builder->where(function ($query) { + + $query->whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL]) ->where('is_deleted', 0) + ->where('balance', '>', 0) ->where(function ($query) { $query->where('due_date', '<', now()) ->orWhere('partial_due_date', '<', now()); }) ->orderBy('due_date', 'ASC'); + }); + } /** From 3a5730e884b6f2b96d6ecacfbb3e78555c88022c Mon Sep 17 00:00:00 2001 From: David Bomba Date: Sat, 9 Dec 2023 11:52:42 +1100 Subject: [PATCH 07/26] Fixes for import validation --- app/Http/Requests/Import/ImportRequest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Http/Requests/Import/ImportRequest.php b/app/Http/Requests/Import/ImportRequest.php index 4cc8ff93489c..44c6fe6d869e 100644 --- a/app/Http/Requests/Import/ImportRequest.php +++ b/app/Http/Requests/Import/ImportRequest.php @@ -37,7 +37,7 @@ class ImportRequest extends Request 'column_map' => 'required_with:hash|array', 'skip_header' => 'required_with:hash|boolean', 'files.*' => 'file|mimes:csv,txt', - 'bank_integration_id' => 'bail|required_if:column_map,bank_transaction|min:2' + 'bank_integration_id' => 'bail|required_with:column_map,bank_transaction|min:2' ]; } } From 0e10e99cb7b49e883ae18f9eca4cca8ca3078bef Mon Sep 17 00:00:00 2001 From: David Bomba Date: Sat, 9 Dec 2023 12:04:55 +1100 Subject: [PATCH 08/26] Update request rules for imports --- app/Http/Requests/Import/ImportRequest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Http/Requests/Import/ImportRequest.php b/app/Http/Requests/Import/ImportRequest.php index 44c6fe6d869e..541f4f1c422c 100644 --- a/app/Http/Requests/Import/ImportRequest.php +++ b/app/Http/Requests/Import/ImportRequest.php @@ -37,7 +37,7 @@ class ImportRequest extends Request 'column_map' => 'required_with:hash|array', 'skip_header' => 'required_with:hash|boolean', 'files.*' => 'file|mimes:csv,txt', - 'bank_integration_id' => 'bail|required_with:column_map,bank_transaction|min:2' + 'bank_integration_id' => 'bail|required_with:column_map.bank_transaction|min:2' ]; } } From 23fb0d4cda43568f04c7e68afb7b124b24ed9669 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Sun, 10 Dec 2023 13:22:51 +1100 Subject: [PATCH 09/26] Updates for readme --- app/Http/Controllers/TwilioController.php | 20 +++++++++++++++++++- app/Jobs/PostMark/ProcessPostmarkWebhook.php | 12 +++++++++--- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/app/Http/Controllers/TwilioController.php b/app/Http/Controllers/TwilioController.php index c43ba09d7365..ed6044995b12 100644 --- a/app/Http/Controllers/TwilioController.php +++ b/app/Http/Controllers/TwilioController.php @@ -22,6 +22,11 @@ use Twilio\Rest\Client; class TwilioController extends BaseController { + private array $invalid_codes = [ + '+21', + '+17152567760', + ]; + public function __construct() { parent::__construct(); @@ -39,7 +44,7 @@ class TwilioController extends BaseController $account = $user->company()->account; - if(stripos($request->phone, '+21') !== false) { + if(!$this->checkPhoneValidity($request->phone)) { return response()->json(['message' => 'This phone number is not supported'], 400); } @@ -70,6 +75,19 @@ class TwilioController extends BaseController return response()->json(['message' => 'Code sent.'], 200); } + private function checkPhoneValidity($phone) + { + foreach($this->invalid_codes as $code){ + + if(stripos($phone, $code) !== false) { + return false; + } + + return true; + + } + } + /** * Show the form for creating a new resource. * diff --git a/app/Jobs/PostMark/ProcessPostmarkWebhook.php b/app/Jobs/PostMark/ProcessPostmarkWebhook.php index b66c27144965..a1b54aff4b81 100644 --- a/app/Jobs/PostMark/ProcessPostmarkWebhook.php +++ b/app/Jobs/PostMark/ProcessPostmarkWebhook.php @@ -305,14 +305,20 @@ class ProcessPostmarkWebhook implements ShouldQueue if($sl) { $this->updateSystemLog($sl, $data); + + if (config('ninja.notification.slack')) { + $this->invitation->company->notification(new EmailSpamNotification($this->invitation->company->account))->ninja(); + } + return; } (new SystemLogger($data, SystemLog::CATEGORY_MAIL, SystemLog::EVENT_MAIL_SPAM_COMPLAINT, SystemLog::TYPE_WEBHOOK_RESPONSE, $this->invitation->contact->client, $this->invitation->company))->handle(); - if (config('ninja.notification.slack')) { - $this->invitation->company->notification(new EmailSpamNotification($this->invitation->company->account))->ninja(); - } +if (config('ninja.notification.slack')) { + $this->invitation->company->notification(new EmailSpamNotification($this->invitation->company->account))->ninja(); +} + } private function discoverInvitation($message_id) From 145e2efe3ca5893463fdf8227aefa6bf410282e7 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Mon, 11 Dec 2023 09:25:58 +1100 Subject: [PATCH 10/26] Fixes for report names --- app/Services/Scheduler/EmailReport.php | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/app/Services/Scheduler/EmailReport.php b/app/Services/Scheduler/EmailReport.php index 9b8acf793445..c73cd0034200 100644 --- a/app/Services/Scheduler/EmailReport.php +++ b/app/Services/Scheduler/EmailReport.php @@ -84,20 +84,20 @@ class EmailReport 'client_balance' => $export = (new ClientBalanceReport($this->scheduler->company, $data)), 'client_sales' => $export = (new ClientSalesReport($this->scheduler->company, $data)), 'user_sales' => $export = (new UserSalesReport($this->scheduler->company, $data)), - 'clients' => $export = (new ClientExport($this->scheduler->company, $data)), - 'client_contacts' => $export = (new ContactExport($this->scheduler->company, $data)), - 'credits' => $export = (new CreditExport($this->scheduler->company, $data)), - 'documents' => $export = (new DocumentExport($this->scheduler->company, $data)), - 'expenses' => $export = (new ExpenseExport($this->scheduler->company, $data)), - 'invoices' => $export = (new InvoiceExport($this->scheduler->company, $data)), - 'invoice_items' => $export = (new InvoiceItemExport($this->scheduler->company, $data)), - 'quotes' => $export = (new QuoteExport($this->scheduler->company, $data)), - 'quote_items' => $export = (new QuoteItemExport($this->scheduler->company, $data)), - 'recurring_invoices' => $export = (new RecurringInvoiceExport($this->scheduler->company, $data)), - 'payments' => $export = (new PaymentExport($this->scheduler->company, $data)), - 'products' => $export = (new ProductExport($this->scheduler->company, $data)), - 'tasks' => $export = (new TaskExport($this->scheduler->company, $data)), 'profitloss' => $export = (new ProfitLoss($this->scheduler->company, $data)), + 'client' => $export = (new ClientExport($this->scheduler->company, $data)), + 'client_contact' => $export = (new ContactExport($this->scheduler->company, $data)), + 'credit' => $export = (new CreditExport($this->scheduler->company, $data)), + 'document' => $export = (new DocumentExport($this->scheduler->company, $data)), + 'expense' => $export = (new ExpenseExport($this->scheduler->company, $data)), + 'invoice' => $export = (new InvoiceExport($this->scheduler->company, $data)), + 'invoice_item' => $export = (new InvoiceItemExport($this->scheduler->company, $data)), + 'quote' => $export = (new QuoteExport($this->scheduler->company, $data)), + 'quote_item' => $export = (new QuoteItemExport($this->scheduler->company, $data)), + 'recurring_invoice' => $export = (new RecurringInvoiceExport($this->scheduler->company, $data)), + 'payment' => $export = (new PaymentExport($this->scheduler->company, $data)), + 'product' => $export = (new ProductExport($this->scheduler->company, $data)), + 'task' => $export = (new TaskExport($this->scheduler->company, $data)), default => $export = false, }; From 934a643dc492f87baf75fe31bd80f642b6069b3e Mon Sep 17 00:00:00 2001 From: David Bomba Date: Mon, 11 Dec 2023 09:28:39 +1100 Subject: [PATCH 11/26] Updates for report names --- app/Http/Requests/TaskScheduler/StoreSchedulerRequest.php | 4 ++-- app/Http/Requests/TaskScheduler/UpdateSchedulerRequest.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/Http/Requests/TaskScheduler/StoreSchedulerRequest.php b/app/Http/Requests/TaskScheduler/StoreSchedulerRequest.php index 4e197ad50e44..1d13a9fafb1a 100644 --- a/app/Http/Requests/TaskScheduler/StoreSchedulerRequest.php +++ b/app/Http/Requests/TaskScheduler/StoreSchedulerRequest.php @@ -42,12 +42,12 @@ class StoreSchedulerRequest extends Request 'template' => 'bail|required|string', 'parameters' => 'bail|array', 'parameters.clients' => ['bail','sometimes', 'array', new ValidClientIds()], - 'parameters.date_range' => 'bail|sometimes|string|in:last7_days,last30_days,last365_days,this_month,last_month,this_quarter,last_quarter,this_year,last_year,all_time,custom', + 'parameters.date_range' => 'bail|sometimes|string|in:last7_days,last30_days,last365_days,this_month,last_month,this_quarter,last_quarter,this_year,last_year,all_time,custom,all', 'parameters.start_date' => ['bail', 'sometimes', 'date:Y-m-d', 'required_if:parameters.date_rate,custom'], 'parameters.end_date' => ['bail', 'sometimes', 'date:Y-m-d', 'required_if:parameters.date_rate,custom', 'after_or_equal:parameters.start_date'], 'parameters.entity' => ['bail', 'sometimes', 'string', 'in:invoice,credit,quote,purchase_order'], 'parameters.entity_id' => ['bail', 'sometimes', 'string'], - 'parameters.report_name' => ['bail','sometimes', 'string', 'required_if:template,email_report','in:ar_detailed,ar_summary,client_balance,tax_summary,profitloss,client_sales,user_sales,product_sales,clients,client_contacts,credits,documents,expenses,invoices,invoice_items,quotes,quote_items,recurring_invoices,payments,products,tasks'], + 'parameters.report_name' => ['bail','sometimes', 'string', 'required_if:template,email_report','in:ar_detailed,ar_summary,client_balance,tax_summary,profitloss,client_sales,user_sales,product_sales,client,client_contact,credit,document,expense,invoice,invoice_item,quote,quote_item,recurring_invoice,payment,product,task'], 'parameters.date_key' => ['bail','sometimes', 'string'], 'parameters.status' => ['bail','sometimes', 'string', 'in:all,draft,paid,unpaid,overdue'], ]; diff --git a/app/Http/Requests/TaskScheduler/UpdateSchedulerRequest.php b/app/Http/Requests/TaskScheduler/UpdateSchedulerRequest.php index f4054949fc85..0e58285ef1ff 100644 --- a/app/Http/Requests/TaskScheduler/UpdateSchedulerRequest.php +++ b/app/Http/Requests/TaskScheduler/UpdateSchedulerRequest.php @@ -39,12 +39,12 @@ class UpdateSchedulerRequest extends Request 'template' => 'bail|required|string', 'parameters' => 'bail|array', 'parameters.clients' => ['bail','sometimes', 'array', new ValidClientIds()], - 'parameters.date_range' => 'bail|sometimes|string|in:last7_days,last30_days,last365_days,this_month,last_month,this_quarter,last_quarter,this_year,last_year,all_time,custom', + 'parameters.date_range' => 'bail|sometimes|string|in:last7_days,last30_days,last365_days,this_month,last_month,this_quarter,last_quarter,this_year,last_year,all_time,custom,all', 'parameters.start_date' => ['bail', 'sometimes', 'date:Y-m-d', 'required_if:parameters.date_rate,custom'], 'parameters.end_date' => ['bail', 'sometimes', 'date:Y-m-d', 'required_if:parameters.date_rate,custom', 'after_or_equal:parameters.start_date'], 'parameters.entity' => ['bail', 'sometimes', 'string', 'in:invoice,credit,quote,purchase_order'], 'parameters.entity_id' => ['bail', 'sometimes', 'string'], - 'parameters.report_name' => ['bail','sometimes', 'string', 'required_if:template,email_report', 'in:ar_detailed,ar_summary,client_balance,tax_summary,profitloss,client_sales,user_sales,product_sales,clients,client_contacts,credits,documents,expenses,invoices,invoice_items,quotes,quote_items,recurring_invoices,payments,products,tasks'], + 'parameters.report_name' => ['bail','sometimes', 'string', 'required_if:template,email_report', 'in:ar_detailed,ar_summary,client_balance,tax_summary,profitloss,client_sales,user_sales,product_sales,client,client_contact,credit,document,expense,invoice,invoice_item,quote,quote_item,recurring_invoice,payment,product,task'], 'parameters.date_key' => ['bail','sometimes', 'string'], ]; From 1126c8518fc51be404a453fde0a262eb2b6abe28 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Mon, 11 Dec 2023 10:00:04 +1100 Subject: [PATCH 12/26] Minor cleanup --- app/Jobs/Util/ReminderJob.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/Jobs/Util/ReminderJob.php b/app/Jobs/Util/ReminderJob.php index b6f0c7b00580..e4cab43e6aff 100644 --- a/app/Jobs/Util/ReminderJob.php +++ b/app/Jobs/Util/ReminderJob.php @@ -307,8 +307,6 @@ class ReminderJob implements ShouldQueue /**Refresh Invoice values*/ $invoice = $invoice->calc()->getInvoice(); - // nlog('adjusting client balance and invoice balance by #'.$invoice->number.' '.($invoice->balance - $temp_invoice_balance)); - // $invoice->client->service()->updateBalance($invoice->balance - $temp_invoice_balance); $invoice->ledger()->updateInvoiceBalance($invoice->balance - $temp_invoice_balance, "Late Fee Adjustment for invoice {$invoice->number}"); $invoice->client->service()->calculateBalance(); From 4c4d18fbe8a00becfd4d8b7741a1d79376e036ab Mon Sep 17 00:00:00 2001 From: David Bomba Date: Mon, 11 Dec 2023 13:14:05 +1100 Subject: [PATCH 13/26] Working on email reports --- .../TaskScheduler/StoreSchedulerRequest.php | 6 +- .../TaskScheduler/UpdateSchedulerRequest.php | 4 + app/Services/Scheduler/EmailReport.php | 2 +- composer.lock | 86 +++++++++---------- 4 files changed, 51 insertions(+), 47 deletions(-) diff --git a/app/Http/Requests/TaskScheduler/StoreSchedulerRequest.php b/app/Http/Requests/TaskScheduler/StoreSchedulerRequest.php index 1d13a9fafb1a..6dfaf8423402 100644 --- a/app/Http/Requests/TaskScheduler/StoreSchedulerRequest.php +++ b/app/Http/Requests/TaskScheduler/StoreSchedulerRequest.php @@ -47,7 +47,7 @@ class StoreSchedulerRequest extends Request 'parameters.end_date' => ['bail', 'sometimes', 'date:Y-m-d', 'required_if:parameters.date_rate,custom', 'after_or_equal:parameters.start_date'], 'parameters.entity' => ['bail', 'sometimes', 'string', 'in:invoice,credit,quote,purchase_order'], 'parameters.entity_id' => ['bail', 'sometimes', 'string'], - 'parameters.report_name' => ['bail','sometimes', 'string', 'required_if:template,email_report','in:ar_detailed,ar_summary,client_balance,tax_summary,profitloss,client_sales,user_sales,product_sales,client,client_contact,credit,document,expense,invoice,invoice_item,quote,quote_item,recurring_invoice,payment,product,task'], + 'parameters.report_name' => ['bail','sometimes', 'string', 'required_if:template,email_report','in:ar_detailed,ar_summary,client_balance,tax_summary,profitloss,client_sales,user_sales,product_sales,activity,client,contact,client_contact,credit,document,expense,invoice,invoice_item,quote,quote_item,recurring_invoice,payment,product,task'], 'parameters.date_key' => ['bail','sometimes', 'string'], 'parameters.status' => ['bail','sometimes', 'string', 'in:all,draft,paid,unpaid,overdue'], ]; @@ -67,6 +67,10 @@ class StoreSchedulerRequest extends Request $input['frequency_id'] = 0; } + if(isset($input['parameters']) && isset($input['parameters']['clients'])) { + $input['parameters']['clients'] = []; + } + $this->replace($input); } } diff --git a/app/Http/Requests/TaskScheduler/UpdateSchedulerRequest.php b/app/Http/Requests/TaskScheduler/UpdateSchedulerRequest.php index 0e58285ef1ff..81a8ad492643 100644 --- a/app/Http/Requests/TaskScheduler/UpdateSchedulerRequest.php +++ b/app/Http/Requests/TaskScheduler/UpdateSchedulerRequest.php @@ -63,6 +63,10 @@ class UpdateSchedulerRequest extends Request $input['frequency_id'] = 0; } + if(isset($input['parameters']) && isset($input['parameters']['clients'])) { + $input['parameters']['clients'] = []; + } + $this->replace($input); diff --git a/app/Services/Scheduler/EmailReport.php b/app/Services/Scheduler/EmailReport.php index c73cd0034200..2a251f8f1786 100644 --- a/app/Services/Scheduler/EmailReport.php +++ b/app/Services/Scheduler/EmailReport.php @@ -70,7 +70,7 @@ class EmailReport 'report_keys' => [] ]; - if (count($this->scheduler->parameters['clients']) >= 1) { + if (isset($this->scheduler->parameters['clients']) && count($this->scheduler->parameters['clients']) >= 1) { $data['clients'] = $this->transformKeys($this->scheduler->parameters['clients']); } diff --git a/composer.lock b/composer.lock index 27dc537efdb9..a35b4329b536 100644 --- a/composer.lock +++ b/composer.lock @@ -485,16 +485,16 @@ }, { "name": "aws/aws-sdk-php", - "version": "3.293.5", + "version": "3.293.7", "source": { "type": "git", "url": "https://github.com/aws/aws-sdk-php.git", - "reference": "f2002e52b382b45231da3f9552033f769acfebd8" + "reference": "3bf86ba8b9bbea2b298f89e6f5edc58de276690b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/f2002e52b382b45231da3f9552033f769acfebd8", - "reference": "f2002e52b382b45231da3f9552033f769acfebd8", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/3bf86ba8b9bbea2b298f89e6f5edc58de276690b", + "reference": "3bf86ba8b9bbea2b298f89e6f5edc58de276690b", "shasum": "" }, "require": { @@ -574,9 +574,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.293.5" + "source": "https://github.com/aws/aws-sdk-php/tree/3.293.7" }, - "time": "2023-12-06T19:09:15+00:00" + "time": "2023-12-08T19:11:21+00:00" }, { "name": "bacon/bacon-qr-code", @@ -6576,16 +6576,16 @@ }, { "name": "nesbot/carbon", - "version": "2.72.0", + "version": "2.72.1", "source": { "type": "git", "url": "https://github.com/briannesbitt/Carbon.git", - "reference": "a6885fcbad2ec4360b0e200ee0da7d9b7c90786b" + "reference": "2b3b3db0a2d0556a177392ff1a3bf5608fa09f78" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/a6885fcbad2ec4360b0e200ee0da7d9b7c90786b", - "reference": "a6885fcbad2ec4360b0e200ee0da7d9b7c90786b", + "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/2b3b3db0a2d0556a177392ff1a3bf5608fa09f78", + "reference": "2b3b3db0a2d0556a177392ff1a3bf5608fa09f78", "shasum": "" }, "require": { @@ -6679,7 +6679,7 @@ "type": "tidelift" } ], - "time": "2023-11-28T10:13:25+00:00" + "time": "2023-12-08T23:47:49+00:00" }, { "name": "nette/schema", @@ -6831,16 +6831,16 @@ }, { "name": "nikic/php-parser", - "version": "v4.17.1", + "version": "v4.18.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d" + "reference": "1bcbb2179f97633e98bbbc87044ee2611c7d7999" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d", - "reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/1bcbb2179f97633e98bbbc87044ee2611c7d7999", + "reference": "1bcbb2179f97633e98bbbc87044ee2611c7d7999", "shasum": "" }, "require": { @@ -6881,9 +6881,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.17.1" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.18.0" }, - "time": "2023-08-13T19:53:39+00:00" + "time": "2023-12-10T21:03:43+00:00" }, { "name": "nunomaduro/termwind", @@ -13841,23 +13841,23 @@ }, { "name": "tijsverkoyen/css-to-inline-styles", - "version": "2.2.6", + "version": "v2.2.7", "source": { "type": "git", "url": "https://github.com/tijsverkoyen/CssToInlineStyles.git", - "reference": "c42125b83a4fa63b187fdf29f9c93cb7733da30c" + "reference": "83ee6f38df0a63106a9e4536e3060458b74ccedb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/tijsverkoyen/CssToInlineStyles/zipball/c42125b83a4fa63b187fdf29f9c93cb7733da30c", - "reference": "c42125b83a4fa63b187fdf29f9c93cb7733da30c", + "url": "https://api.github.com/repos/tijsverkoyen/CssToInlineStyles/zipball/83ee6f38df0a63106a9e4536e3060458b74ccedb", + "reference": "83ee6f38df0a63106a9e4536e3060458b74ccedb", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "php": "^5.5 || ^7.0 || ^8.0", - "symfony/css-selector": "^2.7 || ^3.0 || ^4.0 || ^5.0 || ^6.0" + "symfony/css-selector": "^2.7 || ^3.0 || ^4.0 || ^5.0 || ^6.0 || ^7.0" }, "require-dev": { "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0 || ^7.5 || ^8.5.21 || ^9.5.10" @@ -13888,9 +13888,9 @@ "homepage": "https://github.com/tijsverkoyen/CssToInlineStyles", "support": { "issues": "https://github.com/tijsverkoyen/CssToInlineStyles/issues", - "source": "https://github.com/tijsverkoyen/CssToInlineStyles/tree/2.2.6" + "source": "https://github.com/tijsverkoyen/CssToInlineStyles/tree/v2.2.7" }, - "time": "2023-01-03T09:29:04+00:00" + "time": "2023-12-08T13:03:43+00:00" }, { "name": "turbo124/beacon", @@ -15263,16 +15263,16 @@ }, { "name": "friendsofphp/php-cs-fixer", - "version": "v3.40.2", + "version": "v3.41.1", "source": { "type": "git", "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", - "reference": "4344562a516b76afe8f2d64b2e52214c30d64ed8" + "reference": "8b6ae8dcbaf23f09680643ab832a4a3a260265f6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/4344562a516b76afe8f2d64b2e52214c30d64ed8", - "reference": "4344562a516b76afe8f2d64b2e52214c30d64ed8", + "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/8b6ae8dcbaf23f09680643ab832a4a3a260265f6", + "reference": "8b6ae8dcbaf23f09680643ab832a4a3a260265f6", "shasum": "" }, "require": { @@ -15302,8 +15302,6 @@ "php-cs-fixer/accessible-object": "^1.1", "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.4", "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.4", - "phpspec/prophecy": "^1.17", - "phpspec/prophecy-phpunit": "^2.0", "phpunit/phpunit": "^9.6", "symfony/phpunit-bridge": "^6.3.8 || ^7.0", "symfony/yaml": "^5.4 || ^6.0 || ^7.0" @@ -15344,7 +15342,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.40.2" + "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.41.1" }, "funding": [ { @@ -15352,7 +15350,7 @@ "type": "github" } ], - "time": "2023-12-03T09:21:33+00:00" + "time": "2023-12-10T19:59:27+00:00" }, { "name": "hamcrest/hamcrest-php", @@ -15633,16 +15631,16 @@ }, { "name": "mockery/mockery", - "version": "1.6.6", + "version": "1.6.7", "source": { "type": "git", "url": "https://github.com/mockery/mockery.git", - "reference": "b8e0bb7d8c604046539c1115994632c74dcb361e" + "reference": "0cc058854b3195ba21dc6b1f7b1f60f4ef3a9c06" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/mockery/mockery/zipball/b8e0bb7d8c604046539c1115994632c74dcb361e", - "reference": "b8e0bb7d8c604046539c1115994632c74dcb361e", + "url": "https://api.github.com/repos/mockery/mockery/zipball/0cc058854b3195ba21dc6b1f7b1f60f4ef3a9c06", + "reference": "0cc058854b3195ba21dc6b1f7b1f60f4ef3a9c06", "shasum": "" }, "require": { @@ -15655,9 +15653,7 @@ }, "require-dev": { "phpunit/phpunit": "^8.5 || ^9.6.10", - "psalm/plugin-phpunit": "^0.18.4", - "symplify/easy-coding-standard": "^11.5.0", - "vimeo/psalm": "^4.30" + "symplify/easy-coding-standard": "^12.0.8" }, "type": "library", "autoload": { @@ -15714,7 +15710,7 @@ "security": "https://github.com/mockery/mockery/security/advisories", "source": "https://github.com/mockery/mockery" }, - "time": "2023-08-09T00:03:52+00:00" + "time": "2023-12-10T02:24:34+00:00" }, { "name": "myclabs/deep-copy", @@ -16071,16 +16067,16 @@ }, { "name": "phpstan/phpstan", - "version": "1.10.47", + "version": "1.10.48", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "84dbb33b520ea28b6cf5676a3941f4bae1c1ff39" + "reference": "087ed4b5f4a7a6e8f3bbdfbfe98ce5c181380bc6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/84dbb33b520ea28b6cf5676a3941f4bae1c1ff39", - "reference": "84dbb33b520ea28b6cf5676a3941f4bae1c1ff39", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/087ed4b5f4a7a6e8f3bbdfbfe98ce5c181380bc6", + "reference": "087ed4b5f4a7a6e8f3bbdfbfe98ce5c181380bc6", "shasum": "" }, "require": { @@ -16129,7 +16125,7 @@ "type": "tidelift" } ], - "time": "2023-12-01T15:19:17+00:00" + "time": "2023-12-08T14:34:28+00:00" }, { "name": "phpunit/php-code-coverage", From b250ba613c3373d8988f34921346a325c9b123f5 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Mon, 11 Dec 2023 22:42:50 +1100 Subject: [PATCH 14/26] v5.7.60 --- VERSION.txt | 2 +- .../Requests/Credit/UpdateCreditRequest.php | 2 +- .../Requests/Invoice/UpdateInvoiceRequest.php | 3 +- .../UpdatePurchaseOrderRequest.php | 2 +- .../Requests/Quote/UpdateQuoteRequest.php | 5 +- app/Jobs/Company/CompanyExport.php | 10 +-- app/Jobs/Company/CompanyImport.php | 63 ++++++++++--------- app/Jobs/Mail/PaymentFailedMailer.php | 2 +- .../GoCardless/InstantBankPay.php | 51 ++++++++++++--- .../GoCardlessPaymentDriver.php | 2 +- config/ninja.php | 4 +- 11 files changed, 93 insertions(+), 53 deletions(-) diff --git a/VERSION.txt b/VERSION.txt index bca730d00e5a..d24b80453203 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -5.7.59 \ No newline at end of file +5.7.60 \ No newline at end of file diff --git a/app/Http/Requests/Credit/UpdateCreditRequest.php b/app/Http/Requests/Credit/UpdateCreditRequest.php index 23ee7007b654..4d15796ac139 100644 --- a/app/Http/Requests/Credit/UpdateCreditRequest.php +++ b/app/Http/Requests/Credit/UpdateCreditRequest.php @@ -60,7 +60,7 @@ class UpdateCreditRequest extends Request $rules['file'] = $this->file_validation; } - $rules['number'] = ['bail', 'sometimes', Rule::unique('credits')->where('company_id', $user->company()->id)->ignore($this->credit->id)]; + $rules['number'] = ['bail', 'sometimes', 'nullable', Rule::unique('credits')->where('company_id', $user->company()->id)->ignore($this->credit->id)]; $rules['client_id'] = ['bail', 'sometimes',Rule::in([$this->credit->client_id])]; diff --git a/app/Http/Requests/Invoice/UpdateInvoiceRequest.php b/app/Http/Requests/Invoice/UpdateInvoiceRequest.php index 319f1d9aab91..1591b9912579 100644 --- a/app/Http/Requests/Invoice/UpdateInvoiceRequest.php +++ b/app/Http/Requests/Invoice/UpdateInvoiceRequest.php @@ -59,9 +59,8 @@ class UpdateInvoiceRequest extends Request $rules['id'] = new LockedInvoiceRule($this->invoice); - $rules['number'] = ['bail', 'sometimes', Rule::unique('invoices')->where('company_id', $user->company()->id)->ignore($this->invoice->id)]; + $rules['number'] = ['bail', 'sometimes', 'nullable', Rule::unique('invoices')->where('company_id', $user->company()->id)->ignore($this->invoice->id)]; - $rules['is_amount_discount'] = ['boolean']; $rules['client_id'] = ['bail', 'sometimes', Rule::in([$this->invoice->client_id])]; $rules['line_items'] = 'array'; diff --git a/app/Http/Requests/PurchaseOrder/UpdatePurchaseOrderRequest.php b/app/Http/Requests/PurchaseOrder/UpdatePurchaseOrderRequest.php index d9549f881f98..800eaf8405ca 100644 --- a/app/Http/Requests/PurchaseOrder/UpdatePurchaseOrderRequest.php +++ b/app/Http/Requests/PurchaseOrder/UpdatePurchaseOrderRequest.php @@ -48,7 +48,7 @@ class UpdatePurchaseOrderRequest extends Request $rules = []; - $rules['number'] = ['bail', 'sometimes', Rule::unique('purchase_orders')->where('company_id', $user->company()->id)->ignore($this->purchase_order->id)]; + $rules['number'] = ['bail', 'sometimes', 'nullable', Rule::unique('purchase_orders')->where('company_id', $user->company()->id)->ignore($this->purchase_order->id)]; $rules['vendor_id'] = ['bail', 'sometimes', Rule::in([$this->purchase_order->vendor_id])]; $rules['line_items'] = 'array'; diff --git a/app/Http/Requests/Quote/UpdateQuoteRequest.php b/app/Http/Requests/Quote/UpdateQuoteRequest.php index 4b473825c88a..4294385b15f2 100644 --- a/app/Http/Requests/Quote/UpdateQuoteRequest.php +++ b/app/Http/Requests/Quote/UpdateQuoteRequest.php @@ -55,7 +55,7 @@ class UpdateQuoteRequest extends Request } - $rules['number'] = ['bail', 'sometimes', Rule::unique('quotes')->where('company_id', $user->company()->id)->ignore($this->quote->id)]; + $rules['number'] = ['bail', 'sometimes', 'nullable', Rule::unique('quotes')->where('company_id', $user->company()->id)->ignore($this->quote->id)]; $rules['client_id'] = ['bail', 'sometimes', Rule::in([$this->quote->client_id])]; @@ -73,6 +73,8 @@ class UpdateQuoteRequest extends Request $input = $this->decodePrimaryKeys($input); + $input['id'] = $this->quote->id; + if (isset($input['line_items'])) { $input['line_items'] = isset($input['line_items']) ? $this->cleanItems($input['line_items']) : []; } @@ -85,7 +87,6 @@ class UpdateQuoteRequest extends Request $input['exchange_rate'] = 1; } - $input['id'] = $this->quote->id; $this->replace($input); } diff --git a/app/Jobs/Company/CompanyExport.php b/app/Jobs/Company/CompanyExport.php index 23afdd37738f..0fc36b2500af 100644 --- a/app/Jobs/Company/CompanyExport.php +++ b/app/Jobs/Company/CompanyExport.php @@ -387,19 +387,19 @@ class CompanyExport implements ShouldQueue })->all(); - $this->export_data['bank_integrations'] = $this->company->bank_integrations()->orderBy('id', 'ASC')->cursor()->map(function ($bank_integration) { + $this->export_data['bank_integrations'] = $this->company->bank_integrations()->withTrashed()->orderBy('id', 'ASC')->cursor()->map(function ($bank_integration) { $bank_integration = $this->transformArrayOfKeys($bank_integration, ['account_id','company_id', 'user_id']); - return $bank_integration->makeVisible(['id','user_id','company_id','account_id']); + return $bank_integration->makeVisible(['id','user_id','company_id','account_id','hashed_id']); })->all(); - $this->export_data['bank_transactions'] = $this->company->bank_transactions()->orderBy('id', 'ASC')->cursor()->map(function ($bank_transaction) { - $bank_transaction = $this->transformArrayOfKeys($bank_transaction, ['company_id', 'user_id','bank_integration_id','expense_id','category_id','ninja_category_id','vendor_id']); + $this->export_data['bank_transactions'] = $this->company->bank_transactions()->withTrashed()->orderBy('id', 'ASC')->cursor()->map(function ($bank_transaction) { + $bank_transaction = $this->transformArrayOfKeys($bank_transaction, ['company_id', 'user_id','bank_integration_id','expense_id','ninja_category_id','vendor_id']); return $bank_transaction->makeVisible(['id','user_id','company_id']); })->all(); - $this->export_data['schedulers'] = $this->company->schedulers()->orderBy('id', 'ASC')->cursor()->map(function ($scheduler) { + $this->export_data['schedulers'] = $this->company->schedulers()->withTrashed()->orderBy('id', 'ASC')->cursor()->map(function ($scheduler) { $scheduler = $this->transformArrayOfKeys($scheduler, ['company_id', 'user_id']); return $scheduler->makeVisible(['id','user_id','company_id']); diff --git a/app/Jobs/Company/CompanyImport.php b/app/Jobs/Company/CompanyImport.php index 7c84d721b1e9..44abb45fdf3b 100644 --- a/app/Jobs/Company/CompanyImport.php +++ b/app/Jobs/Company/CompanyImport.php @@ -63,14 +63,12 @@ use App\Utils\Ninja; use App\Utils\TempFile; use App\Utils\Traits\GeneratesCounter; use App\Utils\Traits\MakesHash; -use function GuzzleHttp\json_encode; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; use Illuminate\Support\Facades\App; -use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Storage; use Illuminate\Support\Str; use JsonMachine\JsonDecoder\ExtJsonDecoder; @@ -142,7 +140,6 @@ class CompanyImport implements ShouldQueue 'recurring_expenses', 'expenses', 'tasks', - 'payments', 'company_ledger', 'designs', 'documents', @@ -569,7 +566,7 @@ class CompanyImport implements ShouldQueue ['expenses' => 'expense_id'], ['vendors' => 'vendor_id'], ['expense_categories' => 'ninja_category_id'], - ['expense_categories' => 'category_id'], + // ['expense_categories' => 'category_id'], ['bank_integrations' => 'bank_integration_id'] ], 'bank_transactions', @@ -1143,7 +1140,34 @@ class CompanyImport implements ShouldQueue continue; } + $storage_url = (object)$this->getObject('storage_url', true); + + if (!Storage::exists($document->url) && is_string($storage_url)) { + $url = $storage_url . $document->url; + + $file = @file_get_contents($url); + + + if ($file) { + try { + Storage::disk(config('filesystems.default'))->put($document->url, $file); + + + } catch(\Exception $e) { + nlog($e->getMessage()); + nlog("I could not upload {$document->url}"); + + } + } + else + continue; + + } + else + continue; + $new_document = new Document(); + $new_document->disk = config('filesystems.default'); $new_document->user_id = $this->transformId('users', $document->user_id); $new_document->assigned_user_id = $this->transformId('users', $document->assigned_user_id); $new_document->company_id = $this->company->id; @@ -1169,26 +1193,6 @@ class CompanyImport implements ShouldQueue $new_document->save(['timestamps' => false]); - $storage_url = (object)$this->getObject('storage_url', true); - - if (!Storage::exists($new_document->url) && is_string($storage_url)) { - $url = $storage_url . $new_document->url; - - $file = @file_get_contents($url); - - if ($file) { - try { - Storage::disk(config('filesystems.default'))->put($new_document->url, $file); - - $new_document->disk = config('filesystems.default'); - $new_document->save(); - } catch(\Exception $e) { - nlog($e->getMessage()); - nlog("I could not upload {$new_document->url}"); - $new_document->forceDelete(); - } - } - } } return $this; @@ -1727,7 +1731,9 @@ class CompanyImport implements ShouldQueue */ private function transformId(string $resource, ?string $old): ?int { - if (empty($old)) { + + // WjnegYbwZ1 == 0 return null; + if (empty($old) || $old == 'WjnegYbwZ1') { return null; } @@ -1736,6 +1742,7 @@ class CompanyImport implements ShouldQueue } if (! array_key_exists($resource, $this->ids)) { + $this->sendImportMail("The Import failed due to missing data in the import file. Resource {$resource} not available."); throw new \Exception("Resource {$resource} not available."); @@ -1744,16 +1751,12 @@ class CompanyImport implements ShouldQueue if (! array_key_exists("{$old}", $this->ids[$resource])) { // nlog($this->ids[$resource]); nlog("searching for {$old} in {$resource}"); - - nlog("If we are missing a user - default to the company owner"); if ($resource == 'users') { return $this->company_owner->id; } - $this->sendImportMail("The Import failed due to missing data in the import file. Resource {$resource} not available."); - - nlog($this->ids[$resource]); + $this->sendImportMail("The Import failed due to missing data in the import file. Key {$old} not found in {$resource}."); throw new \Exception("Missing {$resource} key: {$old}"); } diff --git a/app/Jobs/Mail/PaymentFailedMailer.php b/app/Jobs/Mail/PaymentFailedMailer.php index 461b1a01c695..15b9bdb61c8f 100644 --- a/app/Jobs/Mail/PaymentFailedMailer.php +++ b/app/Jobs/Mail/PaymentFailedMailer.php @@ -105,7 +105,7 @@ class PaymentFailedMailer implements ShouldQueue }); //add client payment failures here. - // + if ($this->client->contacts()->whereNotNull('email')->exists() && $this->payment_hash) { $contact = $this->client->contacts()->whereNotNull('email')->first(); diff --git a/app/PaymentDrivers/GoCardless/InstantBankPay.php b/app/PaymentDrivers/GoCardless/InstantBankPay.php index 3d5cf238272a..b6d8f31faea1 100644 --- a/app/PaymentDrivers/GoCardless/InstantBankPay.php +++ b/app/PaymentDrivers/GoCardless/InstantBankPay.php @@ -113,6 +113,10 @@ class InstantBankPay implements MethodInterface return $this->processSuccessfulPayment($payment); } + if ($billing_request->status === 'submitted') { + return $this->processPendingPayment($payment); + } + return $this->processUnsuccessfulPayment($payment); } catch (\Exception $exception) { throw new PaymentFailed( @@ -125,7 +129,40 @@ class InstantBankPay implements MethodInterface /** * Handle pending payments for Instant Bank Transfer. * - * @param ResourcesPayment $payment + * @param \GoCardlessPro\Resources\Payment $payment + * @param array $data + * @return RedirectResponse + */ + public function processPendingPayment(\GoCardlessPro\Resources\Payment $payment, array $data = []) + { + $data = [ + 'payment_method' => $payment->links->mandate, + 'payment_type' => PaymentType::INSTANT_BANK_PAY, + 'amount' => $this->go_cardless->payment_hash->data->amount_with_fee, + 'transaction_reference' => $payment->id, + 'gateway_type_id' => GatewayType::INSTANT_BANK_PAY, + ]; + + $payment = $this->go_cardless->createPayment($data, Payment::STATUS_PENDING); + + SystemLogger::dispatch( + ['response' => $payment, 'data' => $data], + SystemLog::CATEGORY_GATEWAY_RESPONSE, + SystemLog::EVENT_GATEWAY_SUCCESS, + SystemLog::TYPE_GOCARDLESS, + $this->go_cardless->client, + $this->go_cardless->client->company, + ); + + return redirect()->route('client.payments.show', ['payment' => $this->go_cardless->encodePrimaryKey($payment->id)]); + } + + + + /** + * Handle pending payments for Instant Bank Transfer. + * + * @param \GoCardlessPro\Resources\Payment $payment * @param array $data * @return RedirectResponse */ @@ -163,12 +200,12 @@ class InstantBankPay implements MethodInterface { PaymentFailureMailer::dispatch($this->go_cardless->client, $payment->status, $this->go_cardless->client->company, $this->go_cardless->payment_hash->data->amount_with_fee); - PaymentFailureMailer::dispatch( - $this->go_cardless->client, - $payment, - $this->go_cardless->client->company, - $payment->amount - ); + // PaymentFailureMailer::dispatch( + // $this->go_cardless->client, + // $payment, + // $this->go_cardless->client->company, + // $payment->amount + // ); $message = [ 'server_response' => $payment, diff --git a/app/PaymentDrivers/GoCardlessPaymentDriver.php b/app/PaymentDrivers/GoCardlessPaymentDriver.php index 00db105fa717..cca2f9ba8f98 100644 --- a/app/PaymentDrivers/GoCardlessPaymentDriver.php +++ b/app/PaymentDrivers/GoCardlessPaymentDriver.php @@ -165,7 +165,7 @@ class GoCardlessPaymentDriver extends BaseDriver ], ]); - if ($payment->status === 'pending_submission') { + if (in_array($payment->status, ['submitted', 'pending_submission'])) { $this->confirmGatewayFee(); $data = [ diff --git a/config/ninja.php b/config/ninja.php index 94d0a307fc6a..87c3a2fa2a94 100644 --- a/config/ninja.php +++ b/config/ninja.php @@ -17,8 +17,8 @@ return [ 'require_https' => env('REQUIRE_HTTPS', true), 'app_url' => rtrim(env('APP_URL', ''), '/'), 'app_domain' => env('APP_DOMAIN', 'invoicing.co'), - 'app_version' => env('APP_VERSION', '5.7.59'), - 'app_tag' => env('APP_TAG', '5.7.59'), + 'app_version' => env('APP_VERSION', '5.7.60'), + 'app_tag' => env('APP_TAG', '5.7.60'), 'minimum_client_version' => '5.0.16', 'terms_version' => '1.0.1', 'api_secret' => env('API_SECRET', false), From 0db1537539639bf89bf86bb5febe75a57d3ff349 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Mon, 11 Dec 2023 22:56:24 +1100 Subject: [PATCH 15/26] Fixes for scheduler --- app/Http/Requests/TaskScheduler/StoreSchedulerRequest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Http/Requests/TaskScheduler/StoreSchedulerRequest.php b/app/Http/Requests/TaskScheduler/StoreSchedulerRequest.php index 6dfaf8423402..e6e5556174b2 100644 --- a/app/Http/Requests/TaskScheduler/StoreSchedulerRequest.php +++ b/app/Http/Requests/TaskScheduler/StoreSchedulerRequest.php @@ -67,7 +67,7 @@ class StoreSchedulerRequest extends Request $input['frequency_id'] = 0; } - if(isset($input['parameters']) && isset($input['parameters']['clients'])) { + if(isset($input['parameters']) && !isset($input['parameters']['clients'])) { $input['parameters']['clients'] = []; } From 680a1f235cb02d807d13766d48412551f4907275 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Mon, 11 Dec 2023 22:56:40 +1100 Subject: [PATCH 16/26] Fixes for scheduler --- app/Http/Requests/TaskScheduler/UpdateSchedulerRequest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Http/Requests/TaskScheduler/UpdateSchedulerRequest.php b/app/Http/Requests/TaskScheduler/UpdateSchedulerRequest.php index 81a8ad492643..882c5f971271 100644 --- a/app/Http/Requests/TaskScheduler/UpdateSchedulerRequest.php +++ b/app/Http/Requests/TaskScheduler/UpdateSchedulerRequest.php @@ -63,7 +63,7 @@ class UpdateSchedulerRequest extends Request $input['frequency_id'] = 0; } - if(isset($input['parameters']) && isset($input['parameters']['clients'])) { + if(isset($input['parameters']) && !isset($input['parameters']['clients'])) { $input['parameters']['clients'] = []; } From 6238d45bbdbc981c966c1fba80c54099228166bf Mon Sep 17 00:00:00 2001 From: David Bomba Date: Mon, 11 Dec 2023 22:57:39 +1100 Subject: [PATCH 17/26] v5.7.61 --- VERSION.txt | 2 +- config/ninja.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/VERSION.txt b/VERSION.txt index d24b80453203..5fd68abd0349 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -5.7.60 \ No newline at end of file +5.7.61 \ No newline at end of file diff --git a/config/ninja.php b/config/ninja.php index 87c3a2fa2a94..9132ad5f793d 100644 --- a/config/ninja.php +++ b/config/ninja.php @@ -17,8 +17,8 @@ return [ 'require_https' => env('REQUIRE_HTTPS', true), 'app_url' => rtrim(env('APP_URL', ''), '/'), 'app_domain' => env('APP_DOMAIN', 'invoicing.co'), - 'app_version' => env('APP_VERSION', '5.7.60'), - 'app_tag' => env('APP_TAG', '5.7.60'), + 'app_version' => env('APP_VERSION', '5.7.61'), + 'app_tag' => env('APP_TAG', '5.7.61'), 'minimum_client_version' => '5.0.16', 'terms_version' => '1.0.1', 'api_secret' => env('API_SECRET', false), From da60a49e8886b2a0fed4a15a20b1d6b5e7043275 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Tue, 12 Dec 2023 08:21:13 +1100 Subject: [PATCH 18/26] Fixes for exception handling --- app/PaymentDrivers/BaseDriver.php | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/app/PaymentDrivers/BaseDriver.php b/app/PaymentDrivers/BaseDriver.php index 8a324094779f..738cd2de1088 100644 --- a/app/PaymentDrivers/BaseDriver.php +++ b/app/PaymentDrivers/BaseDriver.php @@ -568,7 +568,8 @@ class BaseDriver extends AbstractPaymentDriver $error = array_key_exists('error', $response) ? $response['error'] : 'Undefined Error'; $error_code = array_key_exists('error_code', $response) ? $response['error_code'] : 'Undefined Error Code'; - $this->unWindGatewayFees($this->payment_hash); + if($this->payment_hash) + $this->unWindGatewayFees($this->payment_hash); $this->sendFailureMail($error); @@ -579,10 +580,6 @@ class BaseDriver extends AbstractPaymentDriver $invoices = Invoice::query()->whereIn('id', $this->transformKeys(array_column($this->payment_hash->invoices(), 'invoice_id')))->withTrashed()->get(); - // $invoices->each(function ($invoice) { - // $invoice->service()->deletePdf(); - // }); - $invoices->first()->invitations->each(function ($invitation) use ($nmo) { if (! $invitation->contact->trashed()) { $nmo->to_user = $invitation->contact; From d781f8f15e5feff9a913eab367fa7f18c4ba620e Mon Sep 17 00:00:00 2001 From: David Bomba Date: Tue, 12 Dec 2023 10:46:23 +1100 Subject: [PATCH 19/26] Updates for exports --- app/Export/CSV/ClientExport.php | 28 ++++---- app/Export/CSV/ContactExport.php | 13 +++- app/Export/CSV/CreditExport.php | 36 +++++----- app/Export/CSV/ExpenseExport.php | 40 +++++------ app/Export/CSV/InvoiceExport.php | 34 ++++----- app/Export/CSV/InvoiceItemExport.php | 52 +++++++------- app/Export/CSV/PaymentExport.php | 70 +++++++++---------- app/Export/CSV/PurchaseOrderExport.php | 13 +++- app/Export/CSV/PurchaseOrderItemExport.php | 10 +++ app/Export/CSV/QuoteExport.php | 4 +- app/Export/CSV/QuoteItemExport.php | 22 +++--- app/Export/CSV/RecurringInvoiceExport.php | 44 ++++++------ app/Export/CSV/TaskExport.php | 11 ++- app/Export/CSV/VendorExport.php | 16 +++-- app/Jobs/Company/CreateCompany.php | 2 +- .../GoCardless/InstantBankPay.php | 4 +- app/Transformers/ActivityTransformer.php | 60 +++++++++++++++- phpstan.neon | 3 +- 18 files changed, 282 insertions(+), 180 deletions(-) diff --git a/app/Export/CSV/ClientExport.php b/app/Export/CSV/ClientExport.php index 7f71304cb99b..501b01ab59fc 100644 --- a/app/Export/CSV/ClientExport.php +++ b/app/Export/CSV/ClientExport.php @@ -181,9 +181,9 @@ class ClientExport extends BaseExport } } - return $entity; + // return $entity; - // return $this->decorateAdvancedFields($client, $entity); + return $this->decorateAdvancedFields($client, $entity); } public function processMetaData(array $row, $resource): array @@ -221,21 +221,21 @@ class ClientExport extends BaseExport $entity['client.assigned_user'] = $client->assigned_user ? $client->user->present()->name() : ''; } - if (in_array('client.country_id', $this->input['report_keys'])) { - $entity['client.country_id'] = $client->country ? ctrans("texts.country_{$client->country->name}") : ''; - } + // if (in_array('client.country_id', $this->input['report_keys'])) { + // $entity['client.country_id'] = $client->country ? ctrans("texts.country_{$client->country->name}") : ''; + // } - if (in_array('client.shipping_country_id', $this->input['report_keys'])) { - $entity['client.shipping_country_id'] = $client->shipping_country ? ctrans("texts.country_{$client->shipping_country->name}") : ''; - } + // if (in_array('client.shipping_country_id', $this->input['report_keys'])) { + // $entity['client.shipping_country_id'] = $client->shipping_country ? ctrans("texts.country_{$client->shipping_country->name}") : ''; + // } - if (in_array('client.currency_id', $this->input['report_keys'])) { - $entity['client.currency_id'] = $client->currency() ? $client->currency()->code : $client->company->currency()->code; - } + // if (in_array('client.currency_id', $this->input['report_keys'])) { + // $entity['client.currency_id'] = $client->currency() ? $client->currency()->code : $client->company->currency()->code; + // } - if (in_array('client.industry_id', $this->input['report_keys'])) { - $entity['industry_id'] = $client->industry ? ctrans("texts.industry_{$client->industry->name}") : ''; - } + // if (in_array('client.industry_id', $this->input['report_keys'])) { + // $entity['industry_id'] = $client->industry ? ctrans("texts.industry_{$client->industry->name}") : ''; + // } if (in_array('client.classification', $this->input['report_keys']) && isset($client->classification)) { $entity['client.classification'] = ctrans("texts.{$client->classification}") ?? ''; diff --git a/app/Export/CSV/ContactExport.php b/app/Export/CSV/ContactExport.php index 1bb0a8b9fd02..ddd6ad078ef6 100644 --- a/app/Export/CSV/ContactExport.php +++ b/app/Export/CSV/ContactExport.php @@ -129,8 +129,8 @@ class ContactExport extends BaseExport } } - return $entity; - // return $this->decorateAdvancedFields($contact->client, $entity); + // return $entity; + return $this->decorateAdvancedFields($contact->client, $entity); } private function decorateAdvancedFields(Client $client, array $entity) :array @@ -151,6 +151,15 @@ class ContactExport extends BaseExport $entity['industry_id'] = $client->industry ? ctrans("texts.industry_{$client->industry->name}") : ''; } + if (in_array('client.user_id', $this->input['report_keys'])) { + $entity['client.user_id'] = $client->user ? $client->user->present()->name() : ''; + } + + if (in_array('client.assigned_user_id', $this->input['report_keys'])) { + $entity['client.assigned_user_id'] = $client->assigned_user ? $client->assigned_user->present()->name() : ''; + } + + return $entity; } } diff --git a/app/Export/CSV/CreditExport.php b/app/Export/CSV/CreditExport.php index dcc9290d9510..e13a91e7a8ed 100644 --- a/app/Export/CSV/CreditExport.php +++ b/app/Export/CSV/CreditExport.php @@ -161,29 +161,29 @@ class CreditExport extends BaseExport private function decorateAdvancedFields(Credit $credit, array $entity) :array { - if (in_array('country_id', $this->input['report_keys'])) { - $entity['country'] = $credit->client->country ? ctrans("texts.country_{$credit->client->country->name}") : ''; - } + // if (in_array('country_id', $this->input['report_keys'])) { + // $entity['country'] = $credit->client->country ? ctrans("texts.country_{$credit->client->country->name}") : ''; + // } - if (in_array('currency_id', $this->input['report_keys'])) { - $entity['currency_id'] = $credit->client->currency() ? $credit->client->currency()->code : $credit->company->currency()->code; - } + // if (in_array('currency_id', $this->input['report_keys'])) { + // $entity['currency_id'] = $credit->client->currency() ? $credit->client->currency()->code : $credit->company->currency()->code; + // } - if (in_array('invoice_id', $this->input['report_keys'])) { - $entity['invoice'] = $credit->invoice ? $credit->invoice->number : ''; - } + // if (in_array('invoice_id', $this->input['report_keys'])) { + // $entity['invoice'] = $credit->invoice ? $credit->invoice->number : ''; + // } - if (in_array('client_id', $this->input['report_keys'])) { - $entity['client'] = $credit->client->present()->name(); - } + // if (in_array('client_id', $this->input['report_keys'])) { + // $entity['client'] = $credit->client->present()->name(); + // } - if (in_array('status_id', $this->input['report_keys'])) { - $entity['status'] = $credit->stringStatus($credit->status_id); - } + // if (in_array('status_id', $this->input['report_keys'])) { + // $entity['status'] = $credit->stringStatus($credit->status_id); + // } - if(in_array('credit.status', $this->input['report_keys'])) { - $entity['credit.status'] = $credit->stringStatus($credit->status_id); - } + // if(in_array('credit.status', $this->input['report_keys'])) { + // $entity['credit.status'] = $credit->stringStatus($credit->status_id); + // } if (in_array('credit.assigned_user_id', $this->input['report_keys'])) { $entity['credit.assigned_user_id'] = $credit->assigned_user ? $credit->assigned_user->present()->name(): ''; diff --git a/app/Export/CSV/ExpenseExport.php b/app/Export/CSV/ExpenseExport.php index a2f48805acb3..ecf5e7a89b4b 100644 --- a/app/Export/CSV/ExpenseExport.php +++ b/app/Export/CSV/ExpenseExport.php @@ -126,35 +126,35 @@ class ExpenseExport extends BaseExport } - return $entity; - // return $this->decorateAdvancedFields($expense, $entity); + // return $entity; + return $this->decorateAdvancedFields($expense, $entity); } private function decorateAdvancedFields(Expense $expense, array $entity) :array { - if (in_array('expense.currency_id', $this->input['report_keys'])) { - $entity['expense.currency_id'] = $expense->currency ? $expense->currency->code : ''; - } + // if (in_array('expense.currency_id', $this->input['report_keys'])) { + // $entity['expense.currency_id'] = $expense->currency ? $expense->currency->code : ''; + // } - if (in_array('expense.client_id', $this->input['report_keys'])) { - $entity['expense.client'] = $expense->client ? $expense->client->present()->name() : ''; - } + // if (in_array('expense.client_id', $this->input['report_keys'])) { + // $entity['expense.client'] = $expense->client ? $expense->client->present()->name() : ''; + // } - if (in_array('expense.invoice_id', $this->input['report_keys'])) { - $entity['expense.invoice_id'] = $expense->invoice ? $expense->invoice->number : ''; - } + // if (in_array('expense.invoice_id', $this->input['report_keys'])) { + // $entity['expense.invoice_id'] = $expense->invoice ? $expense->invoice->number : ''; + // } - if (in_array('expense.category', $this->input['report_keys'])) { - $entity['expense.category'] = $expense->category ? $expense->category->name : ''; - } + // if (in_array('expense.category', $this->input['report_keys'])) { + // $entity['expense.category'] = $expense->category ? $expense->category->name : ''; + // } - if (in_array('expense.vendor_id', $this->input['report_keys'])) { - $entity['expense.vendor'] = $expense->vendor ? $expense->vendor->name : ''; - } + // if (in_array('expense.vendor_id', $this->input['report_keys'])) { + // $entity['expense.vendor'] = $expense->vendor ? $expense->vendor->name : ''; + // } - if (in_array('expense.payment_type_id', $this->input['report_keys'])) { - $entity['expense.payment_type_id'] = $expense->payment_type ? $expense->payment_type->name : ''; - } + // if (in_array('expense.payment_type_id', $this->input['report_keys'])) { + // $entity['expense.payment_type_id'] = $expense->payment_type ? $expense->payment_type->name : ''; + // } if (in_array('expense.project_id', $this->input['report_keys'])) { $entity['expense.project_id'] = $expense->project ? $expense->project->name : ''; diff --git a/app/Export/CSV/InvoiceExport.php b/app/Export/CSV/InvoiceExport.php index 4f28e72fed5d..18b892fafd7d 100644 --- a/app/Export/CSV/InvoiceExport.php +++ b/app/Export/CSV/InvoiceExport.php @@ -128,32 +128,32 @@ class InvoiceExport extends BaseExport } - return $entity; - // return $this->decorateAdvancedFields($invoice, $entity); + // return $entity; + return $this->decorateAdvancedFields($invoice, $entity); } private function decorateAdvancedFields(Invoice $invoice, array $entity) :array { - if (in_array('invoice.country_id', $this->input['report_keys'])) { - $entity['invoice.country_id'] = $invoice->client->country ? ctrans("texts.country_{$invoice->client->country->name}") : ''; - } + // if (in_array('invoice.country_id', $this->input['report_keys'])) { + // $entity['invoice.country_id'] = $invoice->client->country ? ctrans("texts.country_{$invoice->client->country->name}") : ''; + // } - if (in_array('invoice.currency_id', $this->input['report_keys'])) { - $entity['invoice.currency_id'] = $invoice->client->currency() ? $invoice->client->currency()->code : $invoice->company->currency()->code; - } + // if (in_array('invoice.currency_id', $this->input['report_keys'])) { + // $entity['invoice.currency_id'] = $invoice->client->currency() ? $invoice->client->currency()->code : $invoice->company->currency()->code; + // } - if (in_array('invoice.client_id', $this->input['report_keys'])) { - $entity['invoice.client_id'] = $invoice->client->present()->name(); - } + // if (in_array('invoice.client_id', $this->input['report_keys'])) { + // $entity['invoice.client_id'] = $invoice->client->present()->name(); + // } - if (in_array('invoice.status', $this->input['report_keys'])) { - $entity['invoice.status'] = $invoice->stringStatus($invoice->status_id); - } + // if (in_array('invoice.status', $this->input['report_keys'])) { + // $entity['invoice.status'] = $invoice->stringStatus($invoice->status_id); + // } - if (in_array('invoice.recurring_id', $this->input['report_keys'])) { - $entity['invoice.recurring_id'] = $invoice->recurring_invoice->number ?? ''; - } + // if (in_array('invoice.recurring_id', $this->input['report_keys'])) { + // $entity['invoice.recurring_id'] = $invoice->recurring_invoice->number ?? ''; + // } if (in_array('invoice.auto_bill_enabled', $this->input['report_keys'])) { $entity['invoice.auto_bill_enabled'] = $invoice->auto_bill_enabled ? ctrans('texts.yes') : ctrans('texts.no'); diff --git a/app/Export/CSV/InvoiceItemExport.php b/app/Export/CSV/InvoiceItemExport.php index 71fac33e9c21..3ffadb076b7c 100644 --- a/app/Export/CSV/InvoiceItemExport.php +++ b/app/Export/CSV/InvoiceItemExport.php @@ -196,43 +196,43 @@ class InvoiceItemExport extends BaseExport // $entity[$key] = $this->resolveKey($key, $invoice, $this->invoice_transformer); } } - return $entity; - // return $this->decorateAdvancedFields($invoice, $entity); + // return $entity; + return $this->decorateAdvancedFields($invoice, $entity); } private function decorateAdvancedFields(Invoice $invoice, array $entity) :array { - if (in_array('currency_id', $this->input['report_keys'])) { - $entity['currency'] = $invoice->client->currency() ? $invoice->client->currency()->code : $invoice->company->currency()->code; - } + // if (in_array('currency_id', $this->input['report_keys'])) { + // $entity['currency'] = $invoice->client->currency() ? $invoice->client->currency()->code : $invoice->company->currency()->code; + // } - if(array_key_exists('type', $entity)) { - $entity['type'] = $invoice->typeIdString($entity['type']); - } + // if(array_key_exists('type', $entity)) { + // $entity['type'] = $invoice->typeIdString($entity['type']); + // } - if(array_key_exists('tax_category', $entity)) { - $entity['tax_category'] = $invoice->taxTypeString($entity['tax_category']); - } + // if(array_key_exists('tax_category', $entity)) { + // $entity['tax_category'] = $invoice->taxTypeString($entity['tax_category']); + // } - if (in_array('invoice.country_id', $this->input['report_keys'])) { - $entity['invoice.country_id'] = $invoice->client->country ? ctrans("texts.country_{$invoice->client->country->name}") : ''; - } + // if (in_array('invoice.country_id', $this->input['report_keys'])) { + // $entity['invoice.country_id'] = $invoice->client->country ? ctrans("texts.country_{$invoice->client->country->name}") : ''; + // } - if (in_array('invoice.currency_id', $this->input['report_keys'])) { - $entity['invoice.currency_id'] = $invoice->client->currency() ? $invoice->client->currency()->code : $invoice->company->currency()->code; - } + // if (in_array('invoice.currency_id', $this->input['report_keys'])) { + // $entity['invoice.currency_id'] = $invoice->client->currency() ? $invoice->client->currency()->code : $invoice->company->currency()->code; + // } - if (in_array('invoice.client_id', $this->input['report_keys'])) { - $entity['invoice.client_id'] = $invoice->client->present()->name(); - } + // if (in_array('invoice.client_id', $this->input['report_keys'])) { + // $entity['invoice.client_id'] = $invoice->client->present()->name(); + // } - if (in_array('invoice.status', $this->input['report_keys'])) { - $entity['invoice.status'] = $invoice->stringStatus($invoice->status_id); - } + // if (in_array('invoice.status', $this->input['report_keys'])) { + // $entity['invoice.status'] = $invoice->stringStatus($invoice->status_id); + // } - if (in_array('invoice.recurring_id', $this->input['report_keys'])) { - $entity['invoice.recurring_id'] = $invoice->recurring_invoice->number ?? ''; - } + // if (in_array('invoice.recurring_id', $this->input['report_keys'])) { + // $entity['invoice.recurring_id'] = $invoice->recurring_invoice->number ?? ''; + // } if (in_array('invoice.assigned_user_id', $this->input['report_keys'])) { $entity['invoice.assigned_user_id'] = $invoice->assigned_user ? $invoice->assigned_user->present()->name(): ''; diff --git a/app/Export/CSV/PaymentExport.php b/app/Export/CSV/PaymentExport.php index 67b8e41abe90..9ddb9de3cddd 100644 --- a/app/Export/CSV/PaymentExport.php +++ b/app/Export/CSV/PaymentExport.php @@ -125,55 +125,55 @@ class PaymentExport extends BaseExport } - return $entity; - // return $this->decorateAdvancedFields($payment, $entity); + // return $entity; + return $this->decorateAdvancedFields($payment, $entity); } private function decorateAdvancedFields(Payment $payment, array $entity) :array { - if (in_array('status_id', $this->input['report_keys'])) { - $entity['status'] = $payment->stringStatus($payment->status_id); - } + // if (in_array('status_id', $this->input['report_keys'])) { + // $entity['status'] = $payment->stringStatus($payment->status_id); + // } - if (in_array('vendor_id', $this->input['report_keys'])) { - $entity['vendor'] = $payment->vendor()->exists() ? $payment->vendor->name : ''; - } + // if (in_array('vendor_id', $this->input['report_keys'])) { + // $entity['vendor'] = $payment->vendor()->exists() ? $payment->vendor->name : ''; + // } - if (in_array('project_id', $this->input['report_keys'])) { - $entity['project'] = $payment->project()->exists() ? $payment->project->name : ''; - } + // if (in_array('project_id', $this->input['report_keys'])) { + // $entity['project'] = $payment->project()->exists() ? $payment->project->name : ''; + // } - if (in_array('currency_id', $this->input['report_keys'])) { - $entity['currency'] = $payment->currency()->exists() ? $payment->currency->code : ''; - } + // if (in_array('currency_id', $this->input['report_keys'])) { + // $entity['currency'] = $payment->currency()->exists() ? $payment->currency->code : ''; + // } - if (in_array('payment.currency', $this->input['report_keys'])) { - $entity['payment.currency'] = $payment->currency()->exists() ? $payment->currency->code : ''; - } + // if (in_array('payment.currency', $this->input['report_keys'])) { + // $entity['payment.currency'] = $payment->currency()->exists() ? $payment->currency->code : ''; + // } - if (in_array('exchange_currency_id', $this->input['report_keys'])) { - $entity['exchange_currency'] = $payment->exchange_currency()->exists() ? $payment->exchange_currency->code : ''; - } + // if (in_array('exchange_currency_id', $this->input['report_keys'])) { + // $entity['exchange_currency'] = $payment->exchange_currency()->exists() ? $payment->exchange_currency->code : ''; + // } - if (in_array('client_id', $this->input['report_keys'])) { - $entity['client'] = $payment->client->present()->name(); - } + // if (in_array('client_id', $this->input['report_keys'])) { + // $entity['client'] = $payment->client->present()->name(); + // } - if (in_array('type_id', $this->input['report_keys'])) { - $entity['type'] = $payment->translatedType(); - } + // if (in_array('type_id', $this->input['report_keys'])) { + // $entity['type'] = $payment->translatedType(); + // } - if (in_array('payment.method', $this->input['report_keys'])) { - $entity['payment.method'] = $payment->translatedType(); - } + // if (in_array('payment.method', $this->input['report_keys'])) { + // $entity['payment.method'] = $payment->translatedType(); + // } - if (in_array('payment.status', $this->input['report_keys'])) { - $entity['payment.status'] = $payment->stringStatus($payment->status_id); - } + // if (in_array('payment.status', $this->input['report_keys'])) { + // $entity['payment.status'] = $payment->stringStatus($payment->status_id); + // } - if (in_array('gateway_type_id', $this->input['report_keys'])) { - $entity['gateway'] = $payment->gateway_type ? $payment->gateway_type->name : 'Unknown Type'; - } + // if (in_array('gateway_type_id', $this->input['report_keys'])) { + // $entity['gateway'] = $payment->gateway_type ? $payment->gateway_type->name : 'Unknown Type'; + // } if (in_array('payment.assigned_user_id', $this->input['report_keys'])) { $entity['payment.assigned_user_id'] = $payment->assigned_user ? $payment->assigned_user->present()->name() : ''; diff --git a/app/Export/CSV/PurchaseOrderExport.php b/app/Export/CSV/PurchaseOrderExport.php index ff15cb2abc25..ac63c9b13cb3 100644 --- a/app/Export/CSV/PurchaseOrderExport.php +++ b/app/Export/CSV/PurchaseOrderExport.php @@ -173,8 +173,8 @@ class PurchaseOrderExport extends BaseExport } - return $entity; - // return $this->decorateAdvancedFields($purchase_order, $entity); + // return $entity; + return $this->decorateAdvancedFields($purchase_order, $entity); } private function decorateAdvancedFields(PurchaseOrder $purchase_order, array $entity) :array @@ -195,6 +195,15 @@ class PurchaseOrderExport extends BaseExport $entity['purchase_order.status'] = $purchase_order->stringStatus($purchase_order->status_id); } + if (in_array('purchase_order.user_id', $this->input['report_keys'])) { + $entity['purchase_order.user_id'] = $purchase_order->user ? $purchase_order->user->present()->name() : ''; + } + + if (in_array('purchase_order.assigned_user_id', $this->input['report_keys'])) { + $entity['purchase_order.assigned_user_id'] = $purchase_order->assigned_user ? $purchase_order->assigned_user->present()->name() : ''; + } + + return $entity; } } diff --git a/app/Export/CSV/PurchaseOrderItemExport.php b/app/Export/CSV/PurchaseOrderItemExport.php index 1d8fce10582c..320d068ef147 100644 --- a/app/Export/CSV/PurchaseOrderItemExport.php +++ b/app/Export/CSV/PurchaseOrderItemExport.php @@ -206,6 +206,16 @@ class PurchaseOrderItemExport extends BaseExport $entity['status'] = $purchase_order->stringStatus($purchase_order->status_id); } + if (in_array('purchase_order.user_id', $this->input['report_keys'])) { + $entity['purchase_order.user_id'] = $purchase_order->user ? $purchase_order->user->present()->name() : ''; + } + + if (in_array('purchase_order.assigned_user_id', $this->input['report_keys'])) { + $entity['purchase_order.assigned_user_id'] = $purchase_order->assigned_user ? $purchase_order->assigned_user->present()->name() : ''; + } + + + return $entity; } diff --git a/app/Export/CSV/QuoteExport.php b/app/Export/CSV/QuoteExport.php index 5ae717df51c0..5da64b61509e 100644 --- a/app/Export/CSV/QuoteExport.php +++ b/app/Export/CSV/QuoteExport.php @@ -133,8 +133,8 @@ class QuoteExport extends BaseExport } } - return $entity; - // return $this->decorateAdvancedFields($quote, $entity); + // return $entity; + return $this->decorateAdvancedFields($quote, $entity); } private function decorateAdvancedFields(Quote $quote, array $entity) :array diff --git a/app/Export/CSV/QuoteItemExport.php b/app/Export/CSV/QuoteItemExport.php index eafbda850103..df6ebc8cd670 100644 --- a/app/Export/CSV/QuoteItemExport.php +++ b/app/Export/CSV/QuoteItemExport.php @@ -189,22 +189,22 @@ class QuoteItemExport extends BaseExport } } - return $entity; - // return $this->decorateAdvancedFields($quote, $entity); + // return $entity; + return $this->decorateAdvancedFields($quote, $entity); } private function decorateAdvancedFields(Quote $quote, array $entity) :array { - if (in_array('currency_id', $this->input['report_keys'])) { - $entity['currency'] = $quote->client->currency() ? $quote->client->currency()->code : $quote->company->currency()->code; - } + // if (in_array('currency_id', $this->input['report_keys'])) { + // $entity['currency'] = $quote->client->currency() ? $quote->client->currency()->code : $quote->company->currency()->code; + // } - if (in_array('client_id', $this->input['report_keys'])) { - $entity['client'] = $quote->client->present()->name(); - } + // if (in_array('client_id', $this->input['report_keys'])) { + // $entity['client'] = $quote->client->present()->name(); + // } - if (in_array('status_id', $this->input['report_keys'])) { - $entity['status'] = $quote->stringStatus($quote->status_id); - } + // if (in_array('status_id', $this->input['report_keys'])) { + // $entity['status'] = $quote->stringStatus($quote->status_id); + // } if (in_array('quote.assigned_user_id', $this->input['report_keys'])) { $entity['quote.assigned_user_id'] = $quote->assigned_user ? $quote->assigned_user->present()->name(): ''; diff --git a/app/Export/CSV/RecurringInvoiceExport.php b/app/Export/CSV/RecurringInvoiceExport.php index 4e1d3945421b..486ab77abcd6 100644 --- a/app/Export/CSV/RecurringInvoiceExport.php +++ b/app/Export/CSV/RecurringInvoiceExport.php @@ -109,8 +109,6 @@ class RecurringInvoiceExport extends BaseExport private function buildRow(RecurringInvoice $invoice) :array { $transformed_invoice = $this->invoice_transformer->transform($invoice); - $transformed_invoice['frequency_id'] = $invoice->frequencyForKey($invoice->frequency_id); //need to inject this here because it is also a valid key -// nlog($transformed_invoice); $entity = []; @@ -131,36 +129,36 @@ class RecurringInvoiceExport extends BaseExport } } -// nlog($entity); - return $entity; - // return $this->decorateAdvancedFields($invoice, $entity); + + // return $entity; + return $this->decorateAdvancedFields($invoice, $entity); } private function decorateAdvancedFields(RecurringInvoice $invoice, array $entity) :array { - if (in_array('country_id', $this->input['report_keys'])) { - $entity['country'] = $invoice->client->country ? ctrans("texts.country_{$invoice->client->country->name}") : ''; - } + // if (in_array('country_id', $this->input['report_keys'])) { + // $entity['country'] = $invoice->client->country ? ctrans("texts.country_{$invoice->client->country->name}") : ''; + // } - if (in_array('currency_id', $this->input['report_keys'])) { - $entity['currency'] = $invoice->client->currency() ? $invoice->client->currency()->code : $invoice->company->currency()->code; - } + // if (in_array('currency_id', $this->input['report_keys'])) { + // $entity['currency'] = $invoice->client->currency() ? $invoice->client->currency()->code : $invoice->company->currency()->code; + // } - if (in_array('client_id', $this->input['report_keys'])) { - $entity['client'] = $invoice->client->present()->name(); - } + // if (in_array('client_id', $this->input['report_keys'])) { + // $entity['client'] = $invoice->client->present()->name(); + // } - if (in_array('recurring_invoice.status', $this->input['report_keys'])) { - $entity['recurring_invoice.status'] = $invoice->stringStatus($invoice->status_id); - } + // if (in_array('recurring_invoice.status', $this->input['report_keys'])) { + // $entity['recurring_invoice.status'] = $invoice->stringStatus($invoice->status_id); + // } - if (in_array('project_id', $this->input['report_keys'])) { - $entity['project'] = $invoice->project ? $invoice->project->name : ''; - } + // if (in_array('project_id', $this->input['report_keys'])) { + // $entity['project'] = $invoice->project ? $invoice->project->name : ''; + // } - if (in_array('vendor_id', $this->input['report_keys'])) { - $entity['vendor'] = $invoice->vendor ? $invoice->vendor->name : ''; - } + // if (in_array('vendor_id', $this->input['report_keys'])) { + // $entity['vendor'] = $invoice->vendor ? $invoice->vendor->name : ''; + // } if (in_array('recurring_invoice.frequency_id', $this->input['report_keys']) || in_array('frequency_id', $this->input['report_keys'])) { $entity['recurring_invoice.frequency_id'] = $invoice->frequencyForKey($invoice->frequency_id); diff --git a/app/Export/CSV/TaskExport.php b/app/Export/CSV/TaskExport.php index 332c9d8807d9..757dda2c4f72 100644 --- a/app/Export/CSV/TaskExport.php +++ b/app/Export/CSV/TaskExport.php @@ -197,7 +197,7 @@ class TaskExport extends BaseExport $entity['task.duration'] = $task->calcDuration(); } - // $entity = $this->decorateAdvancedFields($task, $entity); + $entity = $this->decorateAdvancedFields($task, $entity); $this->storage_array[] = $entity; @@ -218,6 +218,15 @@ class TaskExport extends BaseExport $entity['task.project_id'] = $task->project()->exists() ? $task->project->name : ''; } + if (in_array('task.user_id', $this->input['report_keys'])) { + $entity['task.user_id'] = $task->user ? $task->user->present()->name() : ''; + } + + if (in_array('task.assigned_user_id', $this->input['report_keys'])) { + $entity['task.assigned_user_id'] = $task->assigned_user ? $task->assigned_user->present()->name() : ''; + } + + return $entity; } } diff --git a/app/Export/CSV/VendorExport.php b/app/Export/CSV/VendorExport.php index 4279724f9111..567c745f5a55 100644 --- a/app/Export/CSV/VendorExport.php +++ b/app/Export/CSV/VendorExport.php @@ -126,15 +126,14 @@ class VendorExport extends BaseExport } elseif (is_array($parts) && $parts[0] == 'vendor_contact' && isset($transformed_contact[$parts[1]])) { $entity[$key] = $transformed_contact[$parts[1]]; } else { - // nlog($key); + $entity[$key] = $this->decorator->transform($key, $vendor); - // $entity[$key] = $this->resolveKey($key, $vendor, $this->vendor_transformer); } } - return $entity; - // return $this->decorateAdvancedFields($vendor, $entity); + // return $entity; + return $this->decorateAdvancedFields($vendor, $entity); } private function decorateAdvancedFields(Vendor $vendor, array $entity) :array @@ -151,6 +150,15 @@ class VendorExport extends BaseExport $entity['vendor.classification'] = ctrans("texts.{$vendor->classification}") ?? ''; } + if (in_array('vendor.user_id', $this->input['report_keys'])) { + $entity['vendor.user_id'] = $vendor->user ? $vendor->user->present()->name() : ''; + } + + if (in_array('vendor.assigned_user_id', $this->input['report_keys'])) { + $entity['vendor.assigned_user_id'] = $vendor->assigned_user ? $vendor->assigned_user->present()->name() : ''; + } + + // $entity['status'] = $this->calculateStatus($vendor); return $entity; diff --git a/app/Jobs/Company/CreateCompany.php b/app/Jobs/Company/CreateCompany.php index 5ca76e3071ed..d8c493cfedbf 100644 --- a/app/Jobs/Company/CreateCompany.php +++ b/app/Jobs/Company/CreateCompany.php @@ -65,7 +65,7 @@ class CreateCompany $company->settings = $settings; $company->db = config('database.default'); $company->enabled_modules = config('ninja.enabled_modules'); - $company->subdomain = isset($this->request['subdomain']) ? $this->request['subdomain'] : ''; + $company->subdomain = isset($this->request['subdomain']) ? $this->request['subdomain'] : MultiDB::randomSubdomainGenerator(); $company->custom_fields = new \stdClass; $company->default_password_timeout = 1800000; $company->client_registration_fields = ClientRegistrationFields::generate(); diff --git a/app/PaymentDrivers/GoCardless/InstantBankPay.php b/app/PaymentDrivers/GoCardless/InstantBankPay.php index b6d8f31faea1..947e2da33add 100644 --- a/app/PaymentDrivers/GoCardless/InstantBankPay.php +++ b/app/PaymentDrivers/GoCardless/InstantBankPay.php @@ -136,10 +136,10 @@ class InstantBankPay implements MethodInterface public function processPendingPayment(\GoCardlessPro\Resources\Payment $payment, array $data = []) { $data = [ - 'payment_method' => $payment->links->mandate, + 'payment_method' => $payment->links->mandate, //@phpstan-ignore tag 'payment_type' => PaymentType::INSTANT_BANK_PAY, 'amount' => $this->go_cardless->payment_hash->data->amount_with_fee, - 'transaction_reference' => $payment->id, + 'transaction_reference' => $payment->id, //@phpstan-ignore tag 'gateway_type_id' => GatewayType::INSTANT_BANK_PAY, ]; diff --git a/app/Transformers/ActivityTransformer.php b/app/Transformers/ActivityTransformer.php index 6d8f465f1e95..84130c74280e 100644 --- a/app/Transformers/ActivityTransformer.php +++ b/app/Transformers/ActivityTransformer.php @@ -98,6 +98,11 @@ class ActivityTransformer extends EntityTransformer public function includeClient(Activity $activity) { + + if (!$activity->client) { + return null; + } + $transformer = new ClientTransformer($this->serializer); return $this->includeItem($activity->client, $transformer, Client::class); @@ -105,6 +110,10 @@ class ActivityTransformer extends EntityTransformer public function includeVendor(Activity $activity) { + if (!$activity->vendor) { + return null; + } + $transformer = new VendorTransformer($this->serializer); return $this->includeItem($activity->vendor, $transformer, Vendor::class); @@ -112,6 +121,11 @@ class ActivityTransformer extends EntityTransformer public function includeContact(Activity $activity) { + + if (!$activity->contact) { + return null; + } + $transformer = new ClientContactTransformer($this->serializer); return $this->includeItem($activity->contact, $transformer, ClientContact::class); @@ -119,6 +133,11 @@ class ActivityTransformer extends EntityTransformer public function includeVendorContact(Activity $activity) { + + if (!$activity->vendor_contact) { + return null; + } + $transformer = new VendorContactTransformer($this->serializer); return $this->includeItem($activity->vendor_contact, $transformer, VendorContact::class); @@ -126,6 +145,11 @@ class ActivityTransformer extends EntityTransformer public function includeRecurringInvoice(Activity $activity) { + + if (!$activity->recurring_invoice) { + return null; + } + $transformer = new RecurringInvoiceTransformer($this->serializer); return $this->includeItem($activity->recurring_invoice, $transformer, RecurringInvoice::class); @@ -133,14 +157,24 @@ class ActivityTransformer extends EntityTransformer public function includePurchaseOrder(Activity $activity) { + + if (!$activity->purchase_order) { + return null; + } + $transformer = new PurchaseOrderTransformer($this->serializer); - return $this->includeItem($activity->purchase_order(), $transformer, PurchaseOrder::class); + return $this->includeItem($activity->purchase_order, $transformer, PurchaseOrder::class); } public function includeQuote(Activity $activity) { + + if (!$activity->quote) { + return null; + } + $transformer = new RecurringInvoiceTransformer($this->serializer); return $this->includeItem($activity->quote, $transformer, Quote::class); @@ -148,6 +182,10 @@ class ActivityTransformer extends EntityTransformer public function includeInvoice(Activity $activity) { + if (!$activity->invoice) { + return null; + } + $transformer = new InvoiceTransformer($this->serializer); return $this->includeItem($activity->invoice, $transformer, Invoice::class); @@ -155,6 +193,10 @@ class ActivityTransformer extends EntityTransformer public function includeCredit(Activity $activity) { + if (!$activity->credit) { + return null; + } + $transformer = new CreditTransformer($this->serializer); return $this->includeItem($activity->credit, $transformer, Credit::class); @@ -162,6 +204,10 @@ class ActivityTransformer extends EntityTransformer public function includePayment(Activity $activity) { + if (!$activity->payment) { + return null; + } + $transformer = new PaymentTransformer($this->serializer); return $this->includeItem($activity->payment, $transformer, Payment::class); @@ -169,6 +215,10 @@ class ActivityTransformer extends EntityTransformer public function includeUser(Activity $activity) { + if (!$activity->user) { + return null; + } + $transformer = new UserTransformer($this->serializer); return $this->includeItem($activity->user, $transformer, User::class); @@ -176,6 +226,10 @@ class ActivityTransformer extends EntityTransformer public function includeExpense(Activity $activity) { + if (!$activity->expense) { + return null; + } + $transformer = new ExpenseTransformer($this->serializer); return $this->includeItem($activity->expense, $transformer, Expense::class); @@ -183,6 +237,10 @@ class ActivityTransformer extends EntityTransformer public function includeTask(Activity $activity) { + if (!$activity->task) { + return null; + } + $transformer = new TaskTransformer($this->serializer); return $this->includeItem($activity->task, $transformer, Task::class); diff --git a/phpstan.neon b/phpstan.neon index a9ed25ec5812..6f2c4251a087 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -28,4 +28,5 @@ parameters: - '#Array has 2 duplicate keys with value#' - '#Call to an undefined method#' - '#makeHidden#' - - '#Socialite#' \ No newline at end of file + - '#Socialite#' + - '#Access to protected property#' \ No newline at end of file From 721c8ed88d71e6f607757e988b5cad75028cf332 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Tue, 12 Dec 2023 10:53:21 +1100 Subject: [PATCH 20/26] Fixes for schedule validation --- .../Requests/TaskScheduler/StoreSchedulerRequest.php | 10 +++++++++- .../Requests/TaskScheduler/UpdateSchedulerRequest.php | 10 ++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/app/Http/Requests/TaskScheduler/StoreSchedulerRequest.php b/app/Http/Requests/TaskScheduler/StoreSchedulerRequest.php index e6e5556174b2..4a8d34fe58b2 100644 --- a/app/Http/Requests/TaskScheduler/StoreSchedulerRequest.php +++ b/app/Http/Requests/TaskScheduler/StoreSchedulerRequest.php @@ -49,7 +49,7 @@ class StoreSchedulerRequest extends Request 'parameters.entity_id' => ['bail', 'sometimes', 'string'], 'parameters.report_name' => ['bail','sometimes', 'string', 'required_if:template,email_report','in:ar_detailed,ar_summary,client_balance,tax_summary,profitloss,client_sales,user_sales,product_sales,activity,client,contact,client_contact,credit,document,expense,invoice,invoice_item,quote,quote_item,recurring_invoice,payment,product,task'], 'parameters.date_key' => ['bail','sometimes', 'string'], - 'parameters.status' => ['bail','sometimes', 'string', 'in:all,draft,paid,unpaid,overdue'], + 'parameters.status' => ['bail','sometimes', 'string'], ]; return $rules; @@ -71,6 +71,14 @@ class StoreSchedulerRequest extends Request $input['parameters']['clients'] = []; } + if(isset($input['parameters']['status'])) { + + $input['parameters']['status'] = collect(explode(",", $input['parameter']['status'])) + ->filter(function($status) { + return in_array($status, ['all','draft','paid','unpaid','overdue']); + })->implode(",") ?? ''; + } + $this->replace($input); } } diff --git a/app/Http/Requests/TaskScheduler/UpdateSchedulerRequest.php b/app/Http/Requests/TaskScheduler/UpdateSchedulerRequest.php index 882c5f971271..1c04329d2806 100644 --- a/app/Http/Requests/TaskScheduler/UpdateSchedulerRequest.php +++ b/app/Http/Requests/TaskScheduler/UpdateSchedulerRequest.php @@ -46,6 +46,7 @@ class UpdateSchedulerRequest extends Request 'parameters.entity_id' => ['bail', 'sometimes', 'string'], 'parameters.report_name' => ['bail','sometimes', 'string', 'required_if:template,email_report', 'in:ar_detailed,ar_summary,client_balance,tax_summary,profitloss,client_sales,user_sales,product_sales,client,client_contact,credit,document,expense,invoice,invoice_item,quote,quote_item,recurring_invoice,payment,product,task'], 'parameters.date_key' => ['bail','sometimes', 'string'], + 'parameters.status' => ['bail','sometimes', 'string'], ]; return $rules; @@ -67,6 +68,15 @@ class UpdateSchedulerRequest extends Request $input['parameters']['clients'] = []; } + if(isset($input['parameters']['status'])) { + + $input['parameters']['status'] = collect(explode(",", $input['parameter']['status'])) + ->filter(function ($status) { + return in_array($status, ['all','draft','paid','unpaid','overdue']); + })->implode(",") ?? ''; + } + + $this->replace($input); From e3b385066bfb036efb4a4aaa1f1b6bce449caa90 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Tue, 12 Dec 2023 11:35:36 +1100 Subject: [PATCH 21/26] Catch for paypal script not loading --- .../views/portal/ninja2020/gateways/paypal/pay.blade.php | 8 ++++++-- .../portal/ninja2020/gateways/paypal/ppcp/pay.blade.php | 8 +++++++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/resources/views/portal/ninja2020/gateways/paypal/pay.blade.php b/resources/views/portal/ninja2020/gateways/paypal/pay.blade.php index c94550d3f331..b4eadbf12835 100644 --- a/resources/views/portal/ninja2020/gateways/paypal/pay.blade.php +++ b/resources/views/portal/ninja2020/gateways/paypal/pay.blade.php @@ -34,7 +34,6 @@ @endpush \ No newline at end of file From 600a4646b7ab4510941360705a89ec4377ebb5f7 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Tue, 12 Dec 2023 11:36:55 +1100 Subject: [PATCH 22/26] Catch for paypal script not loading --- app/Http/Requests/TaskScheduler/StoreSchedulerRequest.php | 2 +- app/Http/Requests/TaskScheduler/UpdateSchedulerRequest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/Http/Requests/TaskScheduler/StoreSchedulerRequest.php b/app/Http/Requests/TaskScheduler/StoreSchedulerRequest.php index 4a8d34fe58b2..fff0e66c47e5 100644 --- a/app/Http/Requests/TaskScheduler/StoreSchedulerRequest.php +++ b/app/Http/Requests/TaskScheduler/StoreSchedulerRequest.php @@ -73,7 +73,7 @@ class StoreSchedulerRequest extends Request if(isset($input['parameters']['status'])) { - $input['parameters']['status'] = collect(explode(",", $input['parameter']['status'])) + $input['parameters']['status'] = collect(explode(",", $input['parameters']['status'])) ->filter(function($status) { return in_array($status, ['all','draft','paid','unpaid','overdue']); })->implode(",") ?? ''; diff --git a/app/Http/Requests/TaskScheduler/UpdateSchedulerRequest.php b/app/Http/Requests/TaskScheduler/UpdateSchedulerRequest.php index 1c04329d2806..2b5ffc4ba7fd 100644 --- a/app/Http/Requests/TaskScheduler/UpdateSchedulerRequest.php +++ b/app/Http/Requests/TaskScheduler/UpdateSchedulerRequest.php @@ -70,7 +70,7 @@ class UpdateSchedulerRequest extends Request if(isset($input['parameters']['status'])) { - $input['parameters']['status'] = collect(explode(",", $input['parameter']['status'])) + $input['parameters']['status'] = collect(explode(",", $input['parameters']['status'])) ->filter(function ($status) { return in_array($status, ['all','draft','paid','unpaid','overdue']); })->implode(",") ?? ''; From 46eb5251892477e11c5e79d03de3b44c2e17f909 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Tue, 12 Dec 2023 11:37:49 +1100 Subject: [PATCH 23/26] Catch for paypal script not loading --- tests/Feature/Scheduler/SchedulerTest.php | 34 ++++++++--------------- 1 file changed, 11 insertions(+), 23 deletions(-) diff --git a/tests/Feature/Scheduler/SchedulerTest.php b/tests/Feature/Scheduler/SchedulerTest.php index 56b70ab5c230..861a2111bd19 100644 --- a/tests/Feature/Scheduler/SchedulerTest.php +++ b/tests/Feature/Scheduler/SchedulerTest.php @@ -445,17 +445,11 @@ class SchedulerTest extends TestCase ]; $response = false; - - try { - $response = $this->withHeaders([ - 'X-API-SECRET' => config('ninja.api_secret'), - 'X-API-TOKEN' => $this->token, - ])->postJson('/api/v1/task_schedulers', $data); - } catch (ValidationException $e) { - $message = json_decode($e->validator->getMessageBag(), 1); - nlog($message); - } - + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->postJson('/api/v1/task_schedulers', $data); + $response->assertStatus(200); $data = $response->json(); @@ -509,19 +503,13 @@ class SchedulerTest extends TestCase $response = false; - try { - $response = $this->withHeaders([ - 'X-API-SECRET' => config('ninja.api_secret'), - 'X-API-TOKEN' => $this->token, - ])->postJson('/api/v1/task_schedulers', $data); - } catch (ValidationException $e) { - $message = json_decode($e->validator->getMessageBag(), 1); - nlog($message); - } - + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->postJson('/api/v1/task_schedulers', $data); + $response->assertStatus(200); - - + $data = [ 'name' => 'A single Client', 'frequency_id' => RecurringInvoice::FREQUENCY_MONTHLY, From 820c76ea4dd8971b0b94e91c6b0e5ead80c20726 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Tue, 12 Dec 2023 14:46:08 +1100 Subject: [PATCH 24/26] Adjustments for default quantities --- app/Http/Requests/Product/StoreProductRequest.php | 7 +++++-- app/Http/Requests/Product/UpdateProductRequest.php | 2 +- app/Transformers/ProductTransformer.php | 2 +- .../views/portal/ninja2020/gateways/paypal/pay.blade.php | 3 ++- .../portal/ninja2020/gateways/paypal/ppcp/pay.blade.php | 2 +- 5 files changed, 10 insertions(+), 6 deletions(-) diff --git a/app/Http/Requests/Product/StoreProductRequest.php b/app/Http/Requests/Product/StoreProductRequest.php index 4dacdbdfca16..285a5f0a6145 100644 --- a/app/Http/Requests/Product/StoreProductRequest.php +++ b/app/Http/Requests/Product/StoreProductRequest.php @@ -23,7 +23,10 @@ class StoreProductRequest extends Request */ public function authorize() : bool { - return auth()->user()->can('create', Product::class); + /** @var \App\Models\User $user */ + $user = auth()->user(); + + return $user->can('create', Product::class); } public function rules() @@ -54,7 +57,7 @@ class StoreProductRequest extends Request { $input = $this->all(); - if (! isset($input['quantity']) || $input['quantity'] < 1) { + if (! isset($input['quantity'])) { $input['quantity'] = 1; } diff --git a/app/Http/Requests/Product/UpdateProductRequest.php b/app/Http/Requests/Product/UpdateProductRequest.php index 36197b90cf4a..11c2449df698 100644 --- a/app/Http/Requests/Product/UpdateProductRequest.php +++ b/app/Http/Requests/Product/UpdateProductRequest.php @@ -56,7 +56,7 @@ class UpdateProductRequest extends Request { $input = $this->all(); - if (! isset($input['quantity']) || $input['quantity'] < 1) { + if (! isset($input['quantity'])) { $input['quantity'] = 1; } diff --git a/app/Transformers/ProductTransformer.php b/app/Transformers/ProductTransformer.php index cc28edc2ed1d..2f769dfb7dec 100644 --- a/app/Transformers/ProductTransformer.php +++ b/app/Transformers/ProductTransformer.php @@ -74,7 +74,7 @@ class ProductTransformer extends EntityTransformer 'notes' => $product->notes ?: '', 'cost' => (float) $product->cost ?: 0, 'price' => (float) $product->price ?: 0, - 'quantity' => (float) $product->quantity ?: 1.0, + 'quantity' => (float) is_numeric($product->quantity) ? $product->quantity : 1.0, 'tax_name1' => $product->tax_name1 ?: '', 'tax_rate1' => (float) $product->tax_rate1 ?: 0, 'tax_name2' => $product->tax_name2 ?: '', diff --git a/resources/views/portal/ninja2020/gateways/paypal/pay.blade.php b/resources/views/portal/ninja2020/gateways/paypal/pay.blade.php index b4eadbf12835..0828d552a248 100644 --- a/resources/views/portal/ninja2020/gateways/paypal/pay.blade.php +++ b/resources/views/portal/ninja2020/gateways/paypal/pay.blade.php @@ -28,12 +28,13 @@ @endsection @push('footer') - +