diff --git a/app/Filters/PaymentTermFilters.php b/app/Filters/PaymentTermFilters.php index 93b62e4ce0a4..86865ecc5ad5 100644 --- a/app/Filters/PaymentTermFilters.php +++ b/app/Filters/PaymentTermFilters.php @@ -112,7 +112,8 @@ class PaymentTermFilters extends QueryFilters */ public function entityFilter() { + return $this->builder->company(); //return $this->builder->whereCompanyId(auth()->user()->company()->id); - return $this->builder->whereCompanyId(auth()->user()->company()->id)->orWhere('company_id', null); + // return $this->builder->whereCompanyId(auth()->user()->company()->id)->orWhere('company_id', null); } } diff --git a/app/Filters/ProjectFilters.php b/app/Filters/ProjectFilters.php index bdd961a867ae..9821dbe627c2 100644 --- a/app/Filters/ProjectFilters.php +++ b/app/Filters/ProjectFilters.php @@ -107,7 +107,6 @@ class ProjectFilters extends QueryFilters $query = DB::table('projects') ->join('companies', 'companies.id', '=', 'projects.company_id') ->where('projects.company_id', '=', $company_id) - //->whereRaw('(projects.name != "" or contacts.first_name != "" or contacts.last_name != "" or contacts.email != "")') // filter out buy now invoices ->select( 'projects.id', 'projects.name', @@ -140,6 +139,8 @@ class ProjectFilters extends QueryFilters public function entityFilter() { //return $this->builder->whereCompanyId(auth()->user()->company()->id); - return $this->builder->whereCompanyId(auth()->user()->company()->id)->orWhere('company_id', null); + // return $this->builder->whereCompanyId(auth()->user()->company()->id)->orWhere('company_id', null); + return $this->builder->company(); + } } diff --git a/app/Filters/QueryFilters.php b/app/Filters/QueryFilters.php index 4d4860eb0077..d5e1bfeee626 100644 --- a/app/Filters/QueryFilters.php +++ b/app/Filters/QueryFilters.php @@ -88,6 +88,8 @@ abstract class QueryFilters } } + // nlog('[Search] SQL: ' . $this->builder->toSql() . " Bindings: " . implode(', ', $this->builder->getBindings())); + return $this->builder->withTrashed(); } diff --git a/app/Filters/RecurringExpenseFilters.php b/app/Filters/RecurringExpenseFilters.php index e8c3c4740436..8a433c896aca 100644 --- a/app/Filters/RecurringExpenseFilters.php +++ b/app/Filters/RecurringExpenseFilters.php @@ -58,7 +58,7 @@ class RecurringExpenseFilters extends QueryFilters return $this->builder; } - $table = 'expenses'; + $table = 'recurring_expenses'; $filters = explode(',', $filter); return $this->builder->where(function ($query) use ($filters, $table) { diff --git a/app/Filters/RecurringInvoiceFilters.php b/app/Filters/RecurringInvoiceFilters.php index 4eb17f127df3..befc31f1d71f 100644 --- a/app/Filters/RecurringInvoiceFilters.php +++ b/app/Filters/RecurringInvoiceFilters.php @@ -53,7 +53,7 @@ class RecurringInvoiceFilters extends QueryFilters return $this->builder; } - $table = 'recurring_'; + $table = 'recurring_invoices'; $filters = explode(',', $filter); return $this->builder->where(function ($query) use ($filters, $table) { diff --git a/app/Http/Controllers/BaseController.php b/app/Http/Controllers/BaseController.php index 716d0deb2c59..af241cd412fb 100644 --- a/app/Http/Controllers/BaseController.php +++ b/app/Http/Controllers/BaseController.php @@ -22,6 +22,7 @@ use App\Utils\Traits\AppSetup; use Illuminate\Contracts\Container\BindingResolutionException; use Illuminate\Database\Eloquent\Builder; use Illuminate\Http\Request; +use Illuminate\Support\Str; use League\Fractal\Manager; use League\Fractal\Pagination\IlluminatePaginatorAdapter; use League\Fractal\Resource\Collection; @@ -619,7 +620,9 @@ class BaseController extends Controller $query->with($includes); - if (auth()->user() && ! auth()->user()->hasPermission('view_'.lcfirst(class_basename($this->entity_type)))) { + // 10-01-2022 need to ensure we snake case properly here to ensure permissions work as expected + // if (auth()->user() && ! auth()->user()->hasPermission('view_'.lcfirst(class_basename($this->entity_type)))) { + if (auth()->user() && ! auth()->user()->hasPermission('view'.lcfirst(class_basename(Str::snake($this->entity_type))))) { $query->where('user_id', '=', auth()->user()->id); } diff --git a/app/Http/Controllers/InvoiceController.php b/app/Http/Controllers/InvoiceController.php index a04392dd6a12..e2c913152178 100644 --- a/app/Http/Controllers/InvoiceController.php +++ b/app/Http/Controllers/InvoiceController.php @@ -401,7 +401,7 @@ class InvoiceController extends BaseController $invoice = $this->invoice_repo->save($request->all(), $invoice); - $invoice->service()->triggeredActions($request)->deletePdf(); + $invoice->service()->triggeredActions($request)->deletePdf()->touchPdf(); event(new InvoiceWasUpdated($invoice, $invoice->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null))); @@ -708,7 +708,7 @@ class InvoiceController extends BaseController } break; case 'cancel': - $invoice = $invoice->service()->handleCancellation()->deletePdf()->save(); + $invoice = $invoice->service()->handleCancellation()->deletePdf()->touchPdf()->save(); if (! $bulk) { $this->itemResponse($invoice); diff --git a/app/Jobs/RecurringInvoice/SendRecurring.php b/app/Jobs/RecurringInvoice/SendRecurring.php index f688ec47dcd2..24de8b99f883 100644 --- a/app/Jobs/RecurringInvoice/SendRecurring.php +++ b/app/Jobs/RecurringInvoice/SendRecurring.php @@ -95,7 +95,7 @@ class SendRecurring implements ShouldQueue $invoice = $this->createRecurringInvitations($invoice); /* 09-01-2022 ensure we create the PDFs at this point in time! */ - $invoice->service()->touchPdf(); + $invoice->service()->touchPdf(true); nlog("updating recurring invoice dates"); /* Set next date here to prevent a recurring loop forming */ diff --git a/app/Jobs/Util/ReminderJob.php b/app/Jobs/Util/ReminderJob.php index 93c61e7482cd..05c2e8f6bfbd 100644 --- a/app/Jobs/Util/ReminderJob.php +++ b/app/Jobs/Util/ReminderJob.php @@ -80,6 +80,8 @@ class ReminderJob implements ShouldQueue $invoice->service()->touchReminder($reminder_template)->save(); $invoice = $this->calcLateFee($invoice, $reminder_template); + $invoice->service()->touchPdf(); + //check if this reminder needs to be emailed if(in_array($reminder_template, ['reminder1','reminder2','reminder3','reminder_endless']) && $invoice->client->getSetting("enable_".$reminder_template)) { diff --git a/app/Listeners/Invoice/InvoiceArchivedActivity.php b/app/Listeners/Invoice/InvoiceArchivedActivity.php index 1ceff8ede006..4b37f0070c08 100644 --- a/app/Listeners/Invoice/InvoiceArchivedActivity.php +++ b/app/Listeners/Invoice/InvoiceArchivedActivity.php @@ -43,7 +43,7 @@ class InvoiceArchivedActivity implements ShouldQueue { MultiDB::setDb($event->company->db); - $event->invoice->service()->deletePdf(); + // $event->invoice->service()->deletePdf(); $fields = new stdClass; diff --git a/app/Models/BaseModel.php b/app/Models/BaseModel.php index 2f82e3561b4b..d1e8c8ce6023 100644 --- a/app/Models/BaseModel.php +++ b/app/Models/BaseModel.php @@ -195,8 +195,11 @@ class BaseModel extends Model // Remove any runs of periods (thanks falstro!) $formatted_number = mb_ereg_replace("([\.]{2,})", '', $formatted_number); - $formatted_number = str_replace(" ", "_", $formatted_number); + // $formatted_number = str_replace(" ", "_", $formatted_number); + //11-01-2021 fixes for multiple spaces + $formatted_number = preg_replace('/\s+/', '_', $formatted_number); + return $formatted_number; } diff --git a/app/PaymentDrivers/BaseDriver.php b/app/PaymentDrivers/BaseDriver.php index a85229956014..a1e3e279eb38 100644 --- a/app/PaymentDrivers/BaseDriver.php +++ b/app/PaymentDrivers/BaseDriver.php @@ -442,7 +442,7 @@ class BaseDriver extends AbstractPaymentDriver $invoices->each(function ($invoice) { - $invoice->service()->deletePdf(); + $invoice->service()->touchPdf(); }); @@ -494,7 +494,7 @@ class BaseDriver extends AbstractPaymentDriver $invoices->each(function ($invoice){ - $invoice->service()->deletePdf(); + $invoice->service()->touchPdf(); }); diff --git a/app/PaymentDrivers/GoCardlessPaymentDriver.php b/app/PaymentDrivers/GoCardlessPaymentDriver.php index 721125409090..1cb6e2fb8183 100644 --- a/app/PaymentDrivers/GoCardlessPaymentDriver.php +++ b/app/PaymentDrivers/GoCardlessPaymentDriver.php @@ -234,6 +234,15 @@ class GoCardlessPaymentDriver extends BaseDriver $this->init(); + + if(!is_array($request->events) || !is_object($request->events)){ + + nlog("No GoCardless events to process in response?"); + return response()->json([], 200); + + } + + foreach ($request->events as $event) { if ($event['action'] === 'confirmed') { $payment = Payment::query() diff --git a/app/PaymentDrivers/MolliePaymentDriver.php b/app/PaymentDrivers/MolliePaymentDriver.php index bab3adcf2e59..78e6b495c295 100644 --- a/app/PaymentDrivers/MolliePaymentDriver.php +++ b/app/PaymentDrivers/MolliePaymentDriver.php @@ -321,7 +321,7 @@ class MolliePaymentDriver extends BaseDriver // we may not have a payment record - in these cases we need to re-construct the payment // record from the meta data in the payment hash. - if($payment && property_exists($payment->metadata, 'payment_hash') && $payment->metadata->payment_hash){ + if($payment && property_exists($payment->metadata, 'hash') && $payment->metadata->hash){ /* Harvest Payment Hash*/ $payment_hash = PaymentHash::where('hash', $payment->metadata->hash)->first(); diff --git a/app/PaymentDrivers/Stripe/BrowserPay.php b/app/PaymentDrivers/Stripe/BrowserPay.php index 22b4cb111cd2..9de0cbcca8fa 100644 --- a/app/PaymentDrivers/Stripe/BrowserPay.php +++ b/app/PaymentDrivers/Stripe/BrowserPay.php @@ -194,13 +194,18 @@ class BrowserPay implements MethodInterface return; } - $domain = config('ninja.app_url'); + // $domain = config('ninja.app_url'); - if (Ninja::isHosted()) { - $domain = isset($this->stripe->company_gateway->company->portal_domain) - ? $this->stripe->company_gateway->company->portal_domain - : $this->stripe->company_gateway->company->domain(); - } + // if (Ninja::isHosted()) { + // $domain = isset($this->stripe->company_gateway->company->portal_domain) + // ? $this->stripe->company_gateway->company->portal_domain + // : $this->stripe->company_gateway->company->domain(); + // } + + $domain = $this->getAppleDomain(); + + if(!$domain) + throw new PaymentFailed('Unable to register Domain with Apple Pay', 500); $response = ApplePayDomain::create([ 'domain_name' => $domain, @@ -212,4 +217,36 @@ class BrowserPay implements MethodInterface $this->stripe->company_gateway->save(); } + + + private function getAppleDomain() + { + + $domain = ''; + + if(Ninja::isHosted()) + { + + if($this->company_gateway->company->portal_mode == 'domain'){ + $domain = $this->company_gateway->company->portal_domain; + } + else{ + $domain = $this->company_gateway->company->subdomain . '.' . config('ninja.app_domain'); + } + + } + else { + + $domain = config('ninja.app_url'); + } + + $parsed_url = parse_url($domain); + + if(array_key_exists('host', $parsed_url)) + return $parsed_url['host']; + + return false; + + } + } diff --git a/app/Services/Invoice/InvoiceService.php b/app/Services/Invoice/InvoiceService.php index 23c50125c89d..281cea3ebc8d 100644 --- a/app/Services/Invoice/InvoiceService.php +++ b/app/Services/Invoice/InvoiceService.php @@ -390,18 +390,27 @@ class InvoiceService */ public function touchPdf($force = false) { - if($force){ + try { + + if($force){ + + $this->invoice->invitations->each(function ($invitation) { + CreateEntityPdf::dispatchNow($invitation); + }); + + return $this; + } $this->invoice->invitations->each(function ($invitation) { - CreateEntityPdf::dispatchNow($invitation); + CreateEntityPdf::dispatch($invitation); }); - - return $this; + } + catch(\Exception $e){ - $this->invoice->invitations->each(function ($invitation) { - CreateEntityPdf::dispatch($invitation); - }); + nlog("failed creating invoices in Touch PDF"); + + } return $this; } diff --git a/app/Services/Invoice/MarkPaid.php b/app/Services/Invoice/MarkPaid.php index 3178eba97862..49443d4168c6 100644 --- a/app/Services/Invoice/MarkPaid.php +++ b/app/Services/Invoice/MarkPaid.php @@ -89,6 +89,7 @@ class MarkPaid extends AbstractService ->service() ->applyNumber() ->deletePdf() + ->touchPdf() ->save(); $payment->ledger() diff --git a/app/Services/Payment/UpdateInvoicePayment.php b/app/Services/Payment/UpdateInvoicePayment.php index ca5534245416..16c5d9738b2c 100644 --- a/app/Services/Payment/UpdateInvoicePayment.php +++ b/app/Services/Payment/UpdateInvoicePayment.php @@ -87,7 +87,7 @@ class UpdateInvoicePayment $invoice->refresh(); $invoice->service() - ->deletePdf() + ->touchPdf(true) ->workFlow() ->save(); diff --git a/app/Utils/Traits/ClientGroupSettingsSaver.php b/app/Utils/Traits/ClientGroupSettingsSaver.php index e5e11f0619a4..8ed5856a5586 100644 --- a/app/Utils/Traits/ClientGroupSettingsSaver.php +++ b/app/Utils/Traits/ClientGroupSettingsSaver.php @@ -214,7 +214,7 @@ trait ClientGroupSettingsSaver case 'double': return is_float($value) || is_numeric(strval($value)); case 'string': - return method_exists($value, '__toString') || is_null($value) || is_string($value); + return ( is_string( $value ) && method_exists($value, '__toString') ) || is_null($value) || is_string($value); case 'bool': case 'boolean': return is_bool($value) || (int) filter_var($value, FILTER_VALIDATE_BOOLEAN); diff --git a/app/Utils/Traits/CompanyGatewayFeesAndLimitsSaver.php b/app/Utils/Traits/CompanyGatewayFeesAndLimitsSaver.php index 86917956a23d..26c4e5d1b5d9 100644 --- a/app/Utils/Traits/CompanyGatewayFeesAndLimitsSaver.php +++ b/app/Utils/Traits/CompanyGatewayFeesAndLimitsSaver.php @@ -61,7 +61,7 @@ trait CompanyGatewayFeesAndLimitsSaver case 'double': return is_float($value) || is_numeric(strval($value)); case 'string': - return method_exists($value, '__toString') || is_null($value) || is_string($value); + return ( is_string( $value ) && method_exists($value, '__toString') ) || is_null($value) || is_string($value); case 'bool': case 'boolean': return is_bool($value) || (int) filter_var($value, FILTER_VALIDATE_BOOLEAN); diff --git a/app/Utils/Traits/CompanySettingsSaver.php b/app/Utils/Traits/CompanySettingsSaver.php index 7d3de2afde27..cd2534d6ce57 100644 --- a/app/Utils/Traits/CompanySettingsSaver.php +++ b/app/Utils/Traits/CompanySettingsSaver.php @@ -232,7 +232,6 @@ trait CompanySettingsSaver return is_float($value) || is_numeric(strval($value)); case 'string': return (is_string($value) && method_exists($value, '__toString')) || is_null($value) || is_string($value); - //return is_null($value) || is_string($value); case 'bool': case 'boolean': return is_bool($value) || (int) filter_var($value, FILTER_VALIDATE_BOOLEAN); diff --git a/app/Utils/Traits/SettingsSaver.php b/app/Utils/Traits/SettingsSaver.php index aa35e84fd5ea..0699c04325cf 100644 --- a/app/Utils/Traits/SettingsSaver.php +++ b/app/Utils/Traits/SettingsSaver.php @@ -94,7 +94,7 @@ trait SettingsSaver case 'double': return is_float($value) || is_numeric(strval($value)); case 'string': - return method_exists($value, '__toString') || is_null($value) || is_string($value); + return !is_int($value) || ( is_string( $value ) && method_exists($value, '__toString') ) || is_null($value) || is_string($value); case 'bool': case 'boolean': return is_bool($value) || (int) filter_var($value, FILTER_VALIDATE_BOOLEAN); diff --git a/tests/Feature/ProjectApiTest.php b/tests/Feature/ProjectApiTest.php index a9062e742cab..8d8ae594462e 100644 --- a/tests/Feature/ProjectApiTest.php +++ b/tests/Feature/ProjectApiTest.php @@ -84,10 +84,35 @@ class ProjectApiTest extends TestCase $response->assertStatus(302); } + } + + public function testProjectPostFilters() + { + $data = [ + 'name' => "Sherlock", + 'client_id' => $this->client->hashed_id, + ]; + + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->post('/api/v1/projects', $data); + + $response->assertStatus(200); + + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->get('/api/v1/projects?filter=Sherlock'); + + $arr = $response->json(); + + $this->assertEquals(1, count($arr['data'])); } + public function testProjectPut() { $data = [